> ## Documentation Index
> Fetch the complete documentation index at: https://developer.suki.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Microphone Permission Denied or AudioRecorderFailure

> Fix browser microphone permission and deviceId failures that block ambient recording

On Headless Web SDK, microphone start failures come back as **`StartSessionFailed`** or **`ResumeSessionFailed`** with reason **`AudioRecorderFailure`**. That covers failed mic access or start, including when an exact **`deviceId`** is unavailable. It is not a top-level error code on its own.

On Mobile SDK, related cases are **`needMicrophonePermissionRecording`**, **`micIsInUse`**, **`appIsNotActive`**, and **`unableToStartRecording`**.

## Common causes

* The browser blocked microphone permission for your origin.
* You passed an exact `deviceId` that is missing or disconnected. Headless Web SDK does not fall back to the browser default in that case.
* Microphone access needs **HTTPS** in production (Headless Web SDK prerequisites).
* On Mobile SDK, mic permission was not granted, another app holds the mic, or the app is in the background.

## Fix (Headless Web SDK)

<Steps>
  <Step title="Confirm Permission and HTTPS">
    Prompt for microphone permission and confirm the site is allowed. In production, request microphone access over **HTTPS**. If your app is embedded in an iframe, add `allow="microphone; clipboard-write"` on that iframe.
  </Step>

  <Step title="Inspect StartSessionFailed or ResumeSessionFailed">
    On Platform Client, check `code: "StartSessionFailed"` or `code: "ResumeSessionFailed"` with `reason: "AudioRecorderFailure"`, plus `cause` for the underlying `getUserMedia` error. In React `useAmbientSession`, `start` or `resume` often rethrows a string from `error.toString()` that includes those Code and Reason values.
  </Step>

  <Step title="Refresh deviceId and Retry">
    If you pass `config.audio.deviceId` (or `{ audio: { deviceId } }` on Platform Client), refresh your device list, ask the user to pick another mic, then retry. Optional `deviceId` needs Headless Web SDK **v0.3.1** or later. Omitting `deviceId` uses the browser default microphone.
  </Step>

  <Step title="Pause Before Switching Mics">
    Changing `deviceId` while recording does not switch the mic already in use. Call **`pause()`**, then **`resume()`**, after you update the device. There is no public `switchMicrophone` API.
  </Step>
</Steps>

```tsx theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
// Permission unlocks readable device labels in Chromium.
const permissionStream = await navigator.mediaDevices.getUserMedia({
  audio: true,
  video: false,
});
permissionStream.getTracks().forEach((track) => track.stop());

const devices = await navigator.mediaDevices.enumerateDevices();
const inputs = devices.filter((device) => device.kind === "audioinput");
```

<Note>
  When `deviceId` is set, capture uses `getUserMedia` with that exact device. Your app owns device enumeration and picker UI. The Headless Web SDK does not list microphones for you.
</Note>

## Fix (Mobile SDK)

| Error id | What it means | What to do |
| :- | :- | :- |
| `needMicrophonePermissionRecording` | Microphone permission has not been granted | Request mic permission, then retry start or resume |
| `micIsInUse` | Another app is using the microphone | Free the mic in the other app, then retry |
| `appIsNotActive` | Recording cannot start while the app is in the background | Bring the app to the foreground before recording |
| `unableToStartRecording` | Audio engine setup failed | Check inputs and `AVAudioSession` (or platform equivalent) |

## Next steps

<Icon icon="file-lines" iconType="solid" /> **[micIsInUse on Mobile SDK](/documentation/troubleshooting/mic-is-in-use-mobile)** - Free the device microphone

<Icon icon="file-lines" iconType="solid" /> **[AppIsNotActive on Mobile SDK](/documentation/troubleshooting/app-is-not-active-mobile)** - Recording while backgrounded

<Icon icon="file-lines" iconType="solid" /> **[Manage ambient session](/headless-web-sdk/guides/hooks/ambient-session-hook)** - `deviceId`, start, pause, and resume

<Icon icon="file-lines" iconType="solid" /> **[Audio capture best practices](/documentation/how-to/audio-streaming/audio-capture-best-practices)** - Capture format before Partner WebSocket streaming

<Icon icon="file-lines" iconType="solid" /> **[sessionAlreadyExists](/documentation/troubleshooting/session-already-exists)** - Remote ambient session conflicts on create
