dani-garcia/vaultwarden · error · Error

Generation failed: " + jsonResponse.statusText

Error message

Generation failed: " + jsonResponse.statusText

What it means

On the Vaultwarden admin diagnostics page, clicking Generate Support String builds a Markdown report and augments it with live config fetched from GET /admin/diagnostics/config. If that fetch returns a non-2xx status, the script alerts 'Generation failed: <statusText>' and throws new Error(jsonResponse) — note it passes a Response object, not a message, so the thrown error text is useless ('[object Response]' style). The most common non-OK status is 401 because the admin session cookie is missing or expired.

Source

Thrown at src/static/scripts/admin_diagnostics.js:127

    supportString += `* Server/NTP Time Check: ${chk(ntpTimeCheck)}\n`;
    supportString += `* Domain Configuration Check: ${chk(domainCheck)}\n`;
    supportString += `* HTTPS Check: ${chk(httpsCheck)}\n`;
    if (dj.enable_websocket) {
        supportString += `* Websocket Check: ${chk(websocketCheck)}\n`;
    } else {
        supportString += "* Websocket Check: disabled\n";
    }
    supportString += `* HTTP Response Checks: ${chk(httpResponseCheck)}\n`;
    if (dj.invalid_feature_flags != "") {
        supportString += "* Invalid feature flags: true\n";
    }

    const jsonResponse = await fetch(`${BASE_URL}/admin/diagnostics/config`, {
        "headers": { "Accept": "application/json" }
    });
    if (!jsonResponse.ok) {
        alert("Generation failed: " + jsonResponse.statusText);
        throw new Error(jsonResponse);
    }
    const configJson = await jsonResponse.json();

    // Start Config and Details section within a details block which is collapsed by default
    supportString += "\n### Config & Details (Generated via diagnostics page)\n\n";
    supportString += "<details><summary>Show Config & Details</summary>\n";

    // Add overrides if they exists
    if (dj.overrides != "") {
        supportString += `\n**Environment settings which are overridden:** ${dj.overrides}\n`;
    }

    if (dj.invalid_feature_flags != "") {
        supportString += `\n**Invalid feature flags:** ${dj.invalid_feature_flags}\n`;
    }

    // Add http response check messages if they exists
    if (httpResponseCheck === false) {

View on GitHub (pinned to 0cefa4cca7)

Solutions

  1. Re-authenticate at /admin (re-enter the admin token) and retry generation
  2. Make BASE_URL exactly match the URL used to open the admin UI so the session cookie scopes correctly
  3. Verify the reverse proxy forwards the Cookie header without rewriting paths
  4. Inspect server logs for errors on GET /admin/diagnostics/config when statusText suggests 5xx
  5. Fix the script: throw new Error with the HTTP status instead of the Response object

Example fix

// before
if (!jsonResponse.ok) {
    alert("Generation failed: " + jsonResponse.statusText);
    throw new Error(jsonResponse);
}
// after
if (!jsonResponse.ok) {
    const detail = await jsonResponse.text().catch(() => "");
    throw new Error(`Generation failed: HTTP ${jsonResponse.status} ${jsonResponse.statusText} ${detail.slice(0, 200)}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Run before generating the report: fail fast on a dead admin session
async function assertAdminSession(baseUrl) {
    const probe = await fetch(`${baseUrl}/admin/diagnostics/config`, { credentials: 'same-origin', headers: { Accept: 'application/json' } });
    if (probe.status === 401 || probe.status === 403) {
        throw new Error(`Admin session invalid (HTTP ${probe.status}); log in again at ${baseUrl}/admin`);
    }
}

Type guard

const isJsonOk = (r) => r.ok && (r.headers.get('content-type') || '').includes('application/json');

Try / catch

try {
    const jsonResponse = await fetch(`${BASE_URL}/admin/diagnostics/config`, {
        headers: { Accept: 'application/json' },
        credentials: 'same-origin'
    });
    if (!isJsonOk(jsonResponse)) {
        throw new Error(`Config fetch failed: HTTP ${jsonResponse.status} ${jsonResponse.statusText}`);
    }
    const configJson = await jsonResponse.json();
} catch (e) {
    alert(`Generation failed: ${e.message}`);
    throw e;
}

Prevention

When it happens

Trigger: Clicking Generate Support String after the admin session expired, after a server restart (sessions are invalidated), or after ADMIN_TOKEN changed; also a reverse proxy stripping the Cookie header, or a 500 from the config endpoint itself.

Common situations: Accessing the admin UI through a different host/port than BASE_URL; nginx/Traefik not forwarding cookies; CORS/credential issues when BASE_URL mismatches the page origin; instance restarted between login and report generation.


AI-assisted analysis of dani-garcia/vaultwarden@0cefa4cca7 (2026-08-16). Data as JSON: /api/errors/19dfcbfc337d9ae4. Report an issue: GitHub.