MathewSachin/Captura · error · Exception

Failed to acquire next frame: {acquireResult.Result.Code}

Error message

Failed to acquire next frame: {acquireResult.Result.Code}

What it means

Thrown by DuplCapture.Get (src/Captura.Windows/DesktopDuplication/DuplCapture.cs:114) when _frameGrabber.Grab() returns a result whose Result.Failure is true. AcquireNextFrame returned a failing DXGI code (e.g. access-lost, mode-change, device-removed, invalid-call) indicating the OutputDuplication is no longer valid and must be reinitialized.

Source

Thrown at src/Captura.Windows/DesktopDuplication/DuplCapture.cs:114

                var acquireResult = _frameGrabber.Grab();

                if (acquireResult == null)
                {
                    // _device is being used by Desktop Duplication
                    Texture.Device.ImmediateContext.CopySubresourceRegion(_bkpTexture,
                        0,
                        new ResourceRegion(0, 0, 0, _width, _height, 1),
                        Texture,
                        0,
                        TargetPosition.X, TargetPosition.Y);

                    return true;
                }

                if (acquireResult.Result.Failure)
                {
                    throw new Exception($"Failed to acquire next frame: {acquireResult.Result.Code}");
                }

                using (acquireResult.DesktopResource)
                using (var tempTexture = acquireResult.DesktopResource.QueryInterface<Texture2D>())
                {
                    DxMousePointer?.Update(tempTexture, acquireResult.FrameInfo, _deskDupl);

                    Texture.Device.ImmediateContext.CopySubresourceRegion(tempTexture,
                        0,
                        new ResourceRegion(0, 0, 0, _width, _height, 1),
                        Texture,
                        0,
                        TargetPosition.X, TargetPosition.Y);

                    _device.ImmediateContext.CopyResource(tempTexture, _bkpTexture);
                }

                _frameGrabber.Release();

View on GitHub (pinned to 3fdf41529b)

Solutions

  1. On access-lost / mode-change codes, call Init() to recreate _deskDupl and _frameGrabber, then resume.
  2. Stop capture while the session is locked or on a secure desktop and resume after unlock.
  3. Verify the monitor/output is still connected before re-attempting Grab.
  4. Handle D3D11 device-removed by recreating the Device as well as the duplication.

Example fix

// before
if (acquireResult.Result.Failure)
    throw new Exception($"Failed to acquire next frame: {acquireResult.Result.Code}");
// after - reinitialize once on transient invalidation
if (acquireResult.Result.Failure)
{
    if (acquireResult.Result.Code == ResultCode.AccessLost.Code) { Init(); return false; }
    throw new Exception($"Failed to acquire next frame: {acquireResult.Result.Code}");
}
Defensive patterns

Strategy: retry

Validate before calling

// before Grab, sanity-check the output is still connected
if (_deskDupl == null || _device == null) return false;

Try / catch

try { capture.Get(texture, pointer, pos); }
catch (Exception e) when (e.Message.Contains("Failed to acquire next frame")) { capture.Init(); /* reinitialize once, then resume */ }

Prevention

When it happens

Trigger: Grabbing the next desktop frame after the duplication was invalidated: display mode/resolution changed, monitor disconnected/reconnected, secure desktop (UAC) or lock screen shown, the duplication object became stale, or the D3D11 device was removed.

Common situations: User changed resolution/monitor config mid-capture; locked the screen or hit a UAC prompt; monitor went to sleep/disconnected; driver crash removed the device; multi-monitor topology changed.

Related errors


AI-assisted analysis of MathewSachin/Captura@3fdf41529b (2026-08-13). Data as JSON: /api/errors/f4b5d33e3e9a57c9. Report an issue: GitHub.