Support Thread

Help Restoring Our Busted Avatar Upload

Help Restoring Our Busted Avatar Upload — APG vNext Guide

When the avatar upload system in APG vNext stops working entirely — failing silently for all members, throwing a 500 error, or hanging indefinitely — the underlying cause is almost always one of four things: incorrect folder permissions on the upload directory, corrupted temporary files blocking the image processing pipeline, a misconfigured web.config avatar setting, or a deadlocked image processing library. This guide walks through a systematic recovery procedure that addresses each possible cause in order of likelihood.

Understanding How APG vNext Avatar Uploads Work

When a member uploads an avatar, APG vNext follows this sequence:

  1. The browser POSTs the image file to the forum's upload endpoint (/account/avatar/upload)
  2. APG vNext saves the raw file to a temporary directory (%TEMP%\APG_Upload_* or the configured temp path)
  3. The image processing library (System.Drawing or ImageSharp depending on your version) opens the temp file, validates it as a real image, and resizes it to the configured max dimension
  4. The processed image is written to the avatar storage directory (/upfiles/avatars/)
  5. The database is updated with the new avatar path for the member
  6. The temp file is deleted

A failure at any of these steps causes the upload to fail. Identifying which step is failing narrows down the fix.

Step 1 — Check the APG vNext Error Log

Before touching any files or configuration, check what error is actually being thrown:

-- Query the error log for avatar-related errors:
SELECT TOP 20 ErrorType, ErrorMessage, RequestUrl, OccurredAt
FROM   apg_ErrorLog
WHERE  (RequestUrl LIKE '%avatar%' OR ErrorMessage LIKE '%avatar%')
  AND  OccurredAt > DATEADD(DAY, -7, GETDATE())
ORDER  BY OccurredAt DESC;

The error message will tell you exactly which step is failing:

  • UnauthorizedAccessException: Access to path '...upfiles/avatars...' is denied — permission issue on the avatars folder (Step 4)
  • OutOfMemoryException or ExternalException: A generic error occurred in GDI+ — image processing deadlock (Step 3)
  • InvalidOperationException: Image format not supported — uploaded file is corrupted or not a valid image
  • IOException: The process cannot access the file because it is being used by another process — temp file locked (Step 2)

Step 2 — Fix Upload Folder Permissions

The IIS application pool identity needs Modify permission on the avatar upload directory. This is the most common cause of avatar upload failures after a server migration or IIS reconfiguration:

-- Find the app pool name in IIS Manager:
-- Sites > [Your Forum Site] > Application Pools

-- Grant Modify permission (PowerShell, run as Administrator):
$path = "C:\inetpub\wwwroot\forum\upfiles\avatars"
$account = "IIS AppPool\YourAppPoolName"
$acl = Get-Acl $path
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    $account, "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl.SetAccessRule($rule)
Set-Acl $path $acl

-- Verify:
icacls "C:\inetpub\wwwroot\forum\upfiles\avatars"

Also ensure the parent /upfiles/ directory has the same permission, as APG vNext may create subdirectories dynamically.

Step 3 — Clear Corrupted Temp Files

If a previous upload crashed mid-process, it may have left a locked or corrupted temp file that blocks subsequent uploads. The symptom is that uploads hang indefinitely rather than failing quickly:

-- PowerShell: find and remove APG temp upload files:
Get-ChildItem -Path "$env:TEMP" -Filter "APG_Upload_*" | Remove-Item -Force -ErrorAction SilentlyContinue

-- Also clear the ASP.NET temporary files:
$aspnetTemp = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files"
Get-ChildItem $aspnetTemp | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Remove-Item -Recurse -Force

-- Recycle the app pool after clearing:
Restart-WebAppPool -Name "YourAppPoolName"

Step 4 — Switch Image Processing Library

APG vNext 4.x uses System.Drawing.Bitmap for avatar processing. On servers with restricted GDI+ resources (common with constrained app pool identities or after long uptime periods), GDI+ deadlocks and the avatar processing hangs forever. APG vNext 5.x migrated to SixLabors.ImageSharp which is fully managed and doesn't have these issues. If you're on 4.x and experiencing frequent avatar upload hangs:

<!-- web.config: switch to async avatar processing with timeout -->
<add key="APG.Avatar.ProcessAsync"        value="true" />
<add key="APG.Avatar.ProcessTimeoutSec"   value="10" />
<!-- If processing exceeds 10 seconds, it's cancelled and an error is returned -->

Additionally, upgrading to APG vNext 5.x resolves this permanently by removing the GDI+ dependency entirely.

Step 5 — Verify web.config Avatar Settings

<!-- Confirm all avatar settings are correctly set -->
<add key="APG.Avatar.UploadEnabled"   value="true" />
<add key="APG.Avatar.StoragePath"     value="~/upfiles/avatars/" />
<add key="APG.Avatar.MaxFileSizeKB"   value="500" />
<add key="APG.Avatar.MaxDimensionPx"  value="512" />
<add key="APG.Avatar.AllowedFormats"  value="jpg,jpeg,png,gif,webp" />
<add key="APG.Avatar.AutoResize"      value="true" />
<add key="APG.Avatar.ResizeTo"        value="128" />
<add key="APG.Avatar.FallbackMode"    value="Initials" />

Step 6 — Test With a Minimal Image

After applying fixes, test with the smallest possible valid image to isolate whether the issue is size-related:

  • Create a 10x10 pixel PNG (around 1KB)
  • If this uploads successfully but larger images fail: the issue is the resize timeout — increase APG.Avatar.ProcessTimeoutSec
  • If even the 10x10 image fails: the issue is permissions or the image library itself

Post-Recovery: Regenerating Broken Avatars

After fixing the upload system, members whose previous avatar uploads failed may show broken image icons. Trigger a regeneration from the admin panel:

Admin Panel → Tools → Regenerate Avatars
-- This re-processes all stored avatar files and clears any broken cached paths

-- Or via SQL, reset broken avatar paths to trigger the fallback (initials) display:
UPDATE apg_Members
SET    AvatarPath = NULL
WHERE  AvatarPath IS NOT NULL
  AND  AvatarPath NOT LIKE '%gravatar%'
  AND  NOT EXISTS (
    SELECT 1 FROM sys.dm_os_volume_stats(DB_ID(), 1)
    -- This subquery is illustrative - check actual file existence via app logic
);

Related Resources


Looking for more help? Browse the support forum or check the Knowledge Base.