Up front: I’m not a graphics engineer. I’m a network engineer by trade and I build games as a hobby, mostly in Unreal. I used Claude to help read the kernel panic logs and organise this write-up, and I’ve used it for my own game projects too.
So: everything below marked as an observation, a measurement or a test result is something I did and saw directly. Where I’ve guessed at a mechanism I’ve said so explicitly. Treat the guesses as guesses — the testing stands on its own either way.
Companion to “[Mac] Secondary Lighting above Fair hangs the GPU on Enter World and reboots the Mac (M5 Pro, macOS 26.5.2)” by Tesspiezzo. His fix is real and I confirm it on different hardware — it just doesn’t cover the other seven faults.
The eight faults
| # | Setting | Symptom |
|---|---|---|
| 1 | Triple Buffering ON | Colour channels written to exactly zero, one at a time — no setting fully stops this, see below |
| 2 | Advanced Work Submit ON | Same channel loss, independent trigger |
| 3 | Optional GPU Features ON | Hard horizontal colour bands across trunks and walls |
| 4 | Secondary Lightingabove Fair | GPU hang → macOS kernel panic → reboot |
| 5 | Shadow Qualityabove Low | Foliage renders as flat black silhouettes, measured RGB 0,0,0 |
| 6 | Every fresh client launch | Green cast on distant terrain |
| 7 | Shadow Qualityabove Low | Volumetric light stops rendering entirely |
| 8 | Shadow Quality Fair or higher | Shadows offset and oversized, error growing from the top-left corner — Pallysan’s finding, does not reproduce on my hardware |
Faults 1–7 verified individually on my machine. Fault 8 is Pallysan’s, measured on their hardware and not reproducible on mine — included because the test is sound and the result is specific.
They look like one bug from the player’s side, which is why the workaround threads here contradict each other — people fix one and still have the others.
Working configuration
Triple Buffering ....... OFF
Advanced Work Submit ... OFF
Optional GPU Features .. OFF (needs a full client restart)
Secondary Lighting ..... Fair (graphicsLightMode 0, giQuality 1)
Shadow Quality ......... Low
Everything else ........ 10 / maximum
Textures, view distance, ground clutter, particles, SSAO and bloom all run at max without trouble.
Important caveat, and I had this wrong initially. This configuration does not eliminate the colour corruption (faults 1 & 2) — it slows it down. I ran ten minutes clean outdoors and called it fixed; then it tinted in Stormwind within 10–30 seconds. Those settings change the rate, not whether it happens.
/console gxRestart usually clears it — one second to type, and for most of my testing it worked every single time. It is not reliable, though: in my most recent session the corruption survived repeated gxRestart calls and did not clear at all. Use it as a mitigation, not as a fix, and don’t use it to rule things out.
Four things that make testing this misleading
These wasted hours of my time and I think they explain most of the contradictory reports on this forum.
1. Any renderer reset buys a clean window. Toggling a setting, sliding quality down and up, loading a zone, or gxRestart all flush the accumulated corruption and give you correct rendering for a while. That reads as a fix and then stops working. I nearly posted a “fix” that was just this.
Useful baseline: from a stationary camera outdoors, corruption returns to full in about one minute — and in Stormwind it’s visible in 10–30 seconds. If you post a fix here, say how long you ran it and where. A quiet zone will make almost anything look like a fix.
2. Some settings need a full client restart and some don’t, and they sit next to each other. Optional GPU Features needs a restart in both directions — turning it off and running gxRestart does not clear the banding. Advanced Work Submit applies live. Toggle both in one session and you get one live change and one stale value, which makes the result meaningless. Restart between every change.
3. Test on snow, not grass. A faint green cast on grass is arguable and you talk yourself out of it. Snow should be near-neutral, so any cast is obvious. I had been looking at fault #6 for days in forest zones and dismissing it as ambient light.
4. A reboot is not a bigger gxRestart. Loading a character parked in the Deeprun Tram wedged my machine. It kernel panicked and rebooted, I launched a fresh client, and the same character still wouldn’t load. A different character in Stormwind loaded fine. One /console gxRestart on that character, and the stuck one then loaded normally.
So the fault survived a kernel panic, a power cycle and a fresh client launch — but not a renderer restart inside the running client. Don’t treat “I rebooted and it’s still broken” as ruling out renderer state.
State of this one: single occurrence, not yet repeated, and I can’t separate the zone from the character. Reporting it because the constraint is useful even if the repro isn’t nailed down: whatever this is, it’s reconstructed identically on every launch rather than accumulated at runtime. Same signature as fault 6 — wrong from startup, right after a renderer rebuild, unaffected by rebooting. Those may be one fault. That last part is a guess.
Fault 1 & 2 — colour channels written to zero (Triple Buffering, Advanced Work Submit)
What’s actually happening — measured
I spent a long time calling this a “colour cast”. It isn’t. Sampled the same stone wall with Digital Color Meter at three stages of the same session:
Good R 84 G 72 B 53
Yellow R 106 G 86 B 0 ← blue dead
Green R 0 G 66 B 0 ← red dead too
The colours are channel states. Red plus green with no blue is yellow. Green on its own is green. Nothing is being tinted — channels are being written to exactly zero, one at a time, blue first and then red. Green survived in this zone.
Confirmed independently by analysing the frame itself rather than the display: across that whole green wall, 100% of pixels have R=0 and B=0. Not dark — zero. The screenshot carries 72,891 unique colours and the full 0–255 range in every channel, so this isn’t compression.
There’s a control sitting in the same frame. A more distant wall keeps its red — only 3.2% of its pixels at zero — while the near wall has lost it completely. Same frame, same moment, same light. Only the distance differs.
This also explains why the reports on this forum describe different colours. Every one of them is a channel-loss state:
| Reported as | Channels dead |
|---|---|
| magenta | green |
| yellow | blue |
| green | red + blue |
| cyan | red |
| red | green + blue |
Same fault everywhere, different channels dying, presumably ordered by whatever each zone’s lighting leans on. “Like a shader was refusing to add red” from another thread here is the same observation in different words.
What I don’t know is why, or what triggers it. It is not time of day — I ran two to three hours completely clean this morning, then closed the client, relaunched, and it was present immediately and stayed. I can measure what it does. I can’t predict when it starts.
Behaviour
Terrain, models and characters are all affected. Magenta in one zone, green in another, red in a third — same assets, different environment lighting.
It accumulates. Correct on load, progressively worse over the following seconds, from a stationary camera with nothing moving in frame.
Controlled test, everything fixed except time:
- Stood on persistently corrupted ground. Did not move the character or camera again.
- Ran
/console gxRestart— restarts the graphics device in place. - The same ground rendered correctly immediately.
- Screenshots every 10–20s showed it degrading back to the original state in about a minute.
- It then kept going past the original state into saturated red/magenta. It does not appear to be bounded.
What that establishes:
- The location isn’t bad. Reliably-corrupted ground rendered perfectly the instant the device restarted, same spot, same settings. Rules out map data.
- The rebuild is what’s broken, and the rate is measurable.
- Nothing clamps it. It diverges rather than settling on a wrong value.
Other observations: the corruption is selective — at the same distance some objects take a heavy cast while neighbours look nearly correct. There’s a better-looking region that follows the camera, but also patches that stay corrupted when you walk into them — and those clear instantly on gxRestart, which is how I know they’re stale state rather than bad ground. In the worst state there’s a razor-straight diagonal edge across the ground, fully corrupted one side and normal the other, which is what a square terrain chunk boundary looks like from an oblique camera.
Both settings cause this independently. Advanced Work Submit reproduces it with Triple Buffering already off.
No setting I’ve found eliminates it — they change the rate. This is the part I got wrong first time round and I want it stated plainly:
- Advanced Work Submit off → corruption still returns, noticeably slower
- Triple Buffering off → ten minutes clean outdoors, but tints in Stormwind in 10–30 seconds
/console gxRestart→ usually clears it completely, then it rebuilds — but see the caveat above, it has stopped working entirely on me at least once
So the rate varies with something about the scene, not just with elapsed time. It’s slow enough outdoors that a short test looks like a fix, and fast enough in a city that you can’t miss it. If you’re testing a fix for this, test it in a city. Ten clean minutes in a quiet zone means nothing — I know because I posted exactly that conclusion and it was wrong.
Visibility varies by surface too, which is a separate trap. The tint is far easier to see on snow, fog and neutral stone than on grass. “I don’t see it” and “it isn’t there” are not the same claim.
Guess, not fact: a fault that compounds frame over frame is a feedback loop — something reading its own previous output. Triple Buffering and Advanced Work Submit are both about how frames get submitted and presented, which would fit a render target being read back from the wrong buffer in the rotation. I can’t verify that, and it doesn’t obviously explain why the loss is per-channel and sequential.
One more data point on the trigger, and it’s the strangest one. This morning: two to three hours of continuous play, completely clean, no corruption at all. Out of curiosity I quit the client entirely and relaunched — corruption was present from the first frame, and it has not cleared since, including through gxRestart. Whatever state produces this is established at process start, not accumulated during play, at least in that instance. That contradicts the accumulation I measured on other days, so I’m reporting both rather than picking one.
Fault 3 — horizontal banding (Optional GPU Features)
Tall tree trunks and building walls show a hard horizontal band with different lighting above and below, sharp straight line between.
This is the diagnostic to look for. A subtle colour cast is easy to rationalise as art direction; straight bands across trunks are not. If you see them, you still have the bug.
Unlike faults 1 and 2, this survives gxRestart — it’s present from the first frame and never clears in-session. Static fault established at client startup, not drifting state.
I couldn’t tell whether the band sits at a fixed world altitude or a per-object height. The bands don’t all appear at the same screen height, which argues against a single world-space plane, but I can’t call it.
Fault 4 — kernel panic (Secondary Lighting above Fair)
Confirming Tesspiezzo’s finding on different hardware — Mac Studio M4 Max, not an M5 Pro laptop, same build.
panic: userspace watchdog timeout: no successful checkins from
WindowServer (2 induced crashes) in 120 seconds
Across three logged events, the game and macOS’s display server are blocked in the Metal path simultaneously at byte-identical offsets:
WoW main thread: ... -> Metal +141636 -> libsystem_kernel (blocked in kernel)
WindowServer: DispatchQueue "com.apple.SkyLight.mtl_submit"
-> Metal -> IOGPU -> IOKit -> kernel -> GPU kext
GPU kext UUIDs at the bottom of that stack, identical in both panics: 1CC2AF3D-E6EF-3DC2-B32B-8DBD8CAA09B7 and 3F1A6686-F0A3-38C9-91D6-EC343BE4C695
They’re linked, not coincident: 52 WoW threads carry process received importance donation from WindowServer, which macOS sets when a blocked process is waiting on another. On one occasion WoW logged SIGTERM [HANG] at 12:35:29 and the macOS watchdog fired at 12:35:29 — same second, both sides.
GxDeviceLostCount: 0 in every dump. Metal never declares the device lost; work just stops completing.
The most recent panic names the driver and shows the same thing from the kernel side. WoW’s main thread and WindowServer’s ws_main_thread are both TH_WAIT|TH_UNINT in the same path — IOKit → AGXAcceleratorG16X → IOKit. In the kernel’s GPU threads at that moment, IOGPU Submission had run 1.1 seconds earlier and IOGPU Completion 91 seconds earlier, with AGXHardwareWorkLoop still ticking. Work going in, nothing retiring, firmware not dead. (I’m reading that field as time-since-last-run; flagging it in case that’s wrong.)
Why it sometimes panics and sometimes doesn’t: wedged inside the GPU submit, WindowServer’s main thread is TH_UNINT — uninterruptible. The watchdog can’t kill it, both induced crashes fail, kernel panics. When it’s in an ordinary interruptible wait the watchdog kills it cleanly and the session survives. Same stall, different outcome depending on where WindowServer sits when the watchdog fires. That’s why this presents so inconsistently.
There are three outcomes, and macOS records which one you got. I’ve now hit all three, and the firmware distinguishes them:
| Outcome | Evidence |
|---|---|
| Client dies, macOS unaffected | WoW error report only; nothing in DiagnosticReports |
| Kernel panic, machine reboots itself | panic-full-*.panic + ResetCounter with Boot faults: wdog,reset_in_1 |
| Watchdog escalation never completes — machine wedges, needs a forced power-off | No panic file. ResetCounter with Boot faults: rst btn_rst,btn_seq_reset target_off_restart |
That third one I reproduced deliberately after another Mac user reported it. Method: set Secondary Lighting to High at character selection, restart the client, verify the setting took, enter the world — then leave it alone rather than force-quitting. I walked away for 20 minutes. Came back to the Blizzard error reporter on the desktop and then a hard freeze — held the power button.
The “leave it alone” part is the bit that matters. My earlier attempt produced only a client crash because I force-quit as soon as it stopped responding, which is the natural thing to do and which prevents the failure from finishing.
11:57:58 WindowServer watchdog stackshot #1
11:59:18 WindowServer watchdog stackshot #2
11:59:58 WindowServer watchdog stackshot #3
12:00:51 reset
Three watchdog stackshots and the escalation never finished. No panic log was written. The wdog versus btn_rst boot-fault difference is the machine telling you whether the watchdog reset it or a human did — worth checking if you’re reporting one of these, because “it rebooted” and “I had to hold the power button” are genuinely different failures and shouldn’t be filed as the same thing.
Ruled out: uptimes at the three events were 7.9 days, 23 minutes and 20 hours (not drift); 128GB with memoryPressure: False (not exhaustion); ThermalPressureLevelNominal (not throttling); reproduced with a single client instance (not multi-boxing); reproduced on build 1.60.1.69913 after 1.60.1.69893 (not fixed by the update).
Fault 5 — foliage renders black (Shadow Quality above Low)
At Shadow Quality above Low, bushes and grass render as flat black silhouettes. I originally reported this as their shadows drawing black. That was wrong. Comparing a broken frame against a correct one from the same spot, the plants themselves are black — the same bushes render as pale snow-dusted twigs when it’s working. A silhouette with no colour in it just reads as a shadow.
R: 0 G: 0 B: 0
Measured with Digital Color Meter, and confirmed in the frame itself: 6,966 pixels at exactly (0,0,0) in the broken screenshot against 39 in the correct one. Exact zeros rather than very dark — the same signature as faults 1 and 2, where channels are written to zero instead of attenuated. Here all three go at once.
Obvious in snow zones, easy to talk yourself out of on grass. At Ultra High the whole scene collapses to near-total black with scattered polygon fragments; the UI draws correctly on top, so this is in world rendering, not the final composite.
Fault 6 — green cast on every fresh launch
Present with all five workarounds above already applied.
On a fresh client launch, distant terrain renders with a green cast — correct near the camera, going green with distance as a soft gradient. /console gxRestart clears it completely and it stays clear for the session.
Reproduced on three consecutive fresh launches, cleared all three times. Not intermittent — every launch.
Behaviour rules out both other patterns: not the accumulating fault (that crept back within a minute; this doesn’t return at all), not the static fault (that never cleared in-session). This one is wrong from startup, correct after a renderer rebuild, then stable.
Guess, not fact: that pattern fits an initialisation ordering problem — something building lighting data at startup before what it depends on is ready, then getting it right on gxRestart inside an already-warm client. Possibly worth looking at alongside the startup error below.
Fault 7 — volumetric light disappears (Shadow Quality above Low)
At Shadow Quality Fair, the volumetric light in the Dwarven District stops rendering entirely. Set it back to Low and it comes straight back.
Same region of the same scene, three minutes apart, nothing changed but that one setting:
Shadow Quality Fair mean luminance 44.2
Shadow Quality Low mean luminance 151.9
A 3.4× difference in scene brightness. gxRestart does not restore it — only changing the setting back does.
Filing this separately from fault 5 rather than as a variant of it, because raising a quality setting removing an effect is backwards and looks like a different mistake from the black shadows.
Worth knowing if you’re testing anything: this setting changes more than shadows. If you A/B with Shadow Quality you are also toggling volumetric lighting, which will quietly contaminate whatever you thought you were measuring.
Fault 8 — offset and oversized shadows (Shadow Quality Fair or higher)
Not my finding and not reproducible on my hardware — this is Pallysan’s work, measured on an M2 MacBook, 13" 16:10, native 2560×1600. Including it here because the test is sound and the result is the most specific thing in this thread.
At Shadow Quality Fair or higher, shadows appear offset down and to the right, with the error growing with distance from the top-left corner of the screen — zero offset at that corner, roughly double the centre offset at the bottom right. Measured at three in-game resolutions:
2560×1600 ~3/4" right, 1/2" down (at screen centre)
2048×1280 ~2.5" right, 1.5" down
1920×1200 ~3" right, 2" down — shadow visibly double character size
Render Scale has no effect on any of it.
That’s the signature of a shadow buffer held at a fixed size while the viewport changes. Solving their figures backwards for the buffer width gives ~2900, ~2980 and ~2965 across the three resolutions — consistent, which is what a genuinely fixed buffer looks like.
They read it as a 4K buffer. The arithmetic doesn’t support that: 3840 wide predicts a 2.76" offset at their native resolution and they measured three quarters of an inch. 2880 fits all three readings — predicting 0.69" / 2.24" / 2.76" against their 0.75" / 2.5" / 3.0" — and 2880×1800 is the backing store macOS uses for a 2560×1600 Retina panel.
So the buffer looks like it’s being sized to the display’s backing store rather than to the game’s render target. That would also explain the Render Scale result, since Render Scale moves the 3D render target and not the window’s backing size.
Their measurements, my arithmetic. The inch figures are ruler-against-a-screen estimates, so treat the exact number as approximate — the consistency across three resolutions is the solid part.
I cannot reproduce this. Using a caster I’d confirmed was casting, I moved it across the full width of my screen, from top of frame to bottom, and panned 90° around it. No change in offset in any of the three. I also checked for a darkened region anchored to my viewport by tracking fixed screen tiles through a full camera orbit — nothing stayed dark while the world swept underneath.
That’s a negative on my hardware, not a mark against the test. Three resolutions, a consistent derived buffer size, and a control condition that behaves as predicted is a better-run experiment than most of what’s in this thread including mine. Different display, different result — which is itself worth knowing, since it points at the fault depending on the display’s backing geometry rather than on the GPU.
Unconfirmed — reported by others, not reproduced by me
Listing these separately so it’s clear I haven’t tested them. They may be additional faults or additional faces of the ones above.
Severe FPS drops after raising settings post-login. Reported in the Secondary Lighting workaround thread — framerate collapsing when graphics settings are increased after entering the world, distinct from the crash. I haven’t measured this. If it’s real and it scales with time-in-session rather than with the settings themselves, it might be the same unbounded accumulation as faults 1 and 2 showing up as cost rather than colour — but that’s speculation and someone should actually benchmark it.
If anyone can reproduce it with numbers, that’d be worth posting.
Client error logs (_classic_beta_/Errors/)
Main thread, every session:
Error: ASSERTSAFES(internalGraphicsSetting, ...)
Description: GraphicsSettingCallback Error loading RAIDbloomUserMult
File: .../WoW/Source/WorldClient2/WorldParam.cpp Line: 1330
A graphics setting failing to load through its callback during startup, with a file and line number. I have no way to connect it to any specific fault above, but “graphics setting fails to load at startup” and “lighting is wrong from startup until the renderer rebuilds” are at least compatible.
Also nine times across nine sessions, always 15–18s after launch:
Error: ASSERTSAFES(locality != CAS_LOCALITY_ERROR, ...)
Description: Unable to determine locality for BGDL.
FileData ID 8470130 with CAS error not found
CKey[96E3737F73428445F73E8EF79B94E7FC]
File: .../Engine/Source/FileServices/AsyncFileThread.cpp Line: 568
Identical FileData ID and CKey every time. The client runs on without the asset.
The crash reporter has no submit button
When the client crashed, the Blizzard error reporter appeared with only Close — no submit option. None of this reached you automatically. If that’s general to the Mac beta build, your crash telemetry for this platform may be far thinner than the volume of reports on this forum suggests.
Severity ladder
- Colour corruption on lit surfaces — no macOS log of any kind
- Corruption spreads to near geometry and characters — no log
- Black screen, nothing renders — still no log
- WindowServer stalls, watchdog restarts it, session survives
- WindowServer stalls uninterruptibly — kernel panic, machine reboots
Stages 1–3 leave no trace in macOS diagnostics at all, which I suspect is why “green tint”, “black screen” and “my Mac rebooted” read as three unrelated problems here.
Related threads
This isn’t one machine. Hardware across these spans M4 Air, M5 iMac, M2 Max Studio, M3 Ultra Studio, M5 Pro and M4 Max.
The companion thread — same panic, different hardware, names the CVars: [Mac] Secondary Lighting above Fair hangs the GPU on Enter World and reboots the Mac (M5 Pro, macOS 26.5.2)
Colour corruption — reports green where mine is magenta (“like a shader was refusing to add red”), and independently found that disabling Optional GPU Features cleared their green tint: MacOS client rendering issues and/or locking up
Secondary Lighting workaround, partial for many — includes “complete system reboots when adjusting graphics to maximum levels”: Mac Crashing Solution! Turn "SECONDARY LIGHTING" to "FAIR"
Whole machine freezing on entering the world, on much smaller hardware: WoW: Forever Beta freezes entire Mac when entering the world — MacBook Air M4, macOS 26.6.2
There are more Mac crash threads than these in the Beta Discussion and Mac Technical Support forums — I’ve linked the ones that add something specific rather than every one I found.
And the official Known Issues list for this beta: WoW Forever Beta Known Issues - September 18
Roughly 25 acknowledged issues on it — barber chairs, LUA errors, minimap placement, talent interactions. Not one entry about macOS, graphics corruption, lighting, shadows, black screens, crashes or system freezes. Given the threads above involve Macs kernel panicking, and given the crash reporter on this build has no submit button, I suspect these reports simply aren’t reaching anyone.
System
Mac Studio (2025), M4 Max, 16-core CPU / 40-core GPU, 128 GB unified memory
macOS 26.5 (25F71) at the time of the panics, 26.7 (25G229) now — reproduces on both
5 external displays, 2560x1440, render scale 100%
Graphics API: Metal
Forever beta 1.60.1.69893 and .69913 — reproduces on both
Full kernel panic logs, WindowServer watchdog stackshots and client error dumps available to anyone at Blizzard who wants them.