dubinc/dub · warning

Not found

Error message

Not found

What it means

The local OAuth callback HTTP server (listening on port 4587 during `login`) responds with HTTP 404 and the plain-text body "Not found" for any request that is not a GET to the /callback path. This body surfaces in the browser tab that the OAuth flow opened, and is expected behavior for stray requests rather than a thrown exception.

Source

Thrown at packages/cli/src/api/callback.ts:27

interface OAuthCallbackServerProps {
  oauthClient: OAuth2Client;
  redirectUri: string;
  spinner: Ora;
  codeVerifier: string;
}

export function oauthCallbackServer({
  oauthClient,
  redirectUri,
  codeVerifier,
  spinner,
}: OAuthCallbackServerProps) {
  const server = http.createServer(async (req, res) => {
    const reqUrl = url.parse(req.url || "", true);

    if (reqUrl.pathname !== "/callback" || req.method !== "GET") {
      res.writeHead(404);
      res.end("Not found");
      return;
    }

    const code = reqUrl.query.code as string;

    if (!code) {
      res.writeHead(400);
      res.end(
        "Authorization code not found. Please start the login process again.",
      );

      return;
    }

    try {
      spinner.text = "Verifying";

View on GitHub (pinned to f216b94a24)

Solutions

  1. Make sure the OAuth app's registered redirect URI is exactly http://localhost:4587/callback (matching path, no trailing slash).
  2. Complete the flow by following the provider's redirect rather than typing the URL by hand.
  3. If a proxy or dev tool rewrites the path, disable it for localhost:4587 during login.
  4. Restart `login` if the browser landed on the wrong URL — a fresh flow issues a new authorization code.

Example fix

// before (OAuth app settings)
redirect_uri = http://localhost:4587/callback/
// after
redirect_uri = http://localhost:4587/callback
Defensive patterns

Strategy: validation

Validate before calling

// Verify the redirect URI before starting the flow
const redirectUri = 'http://localhost:4587/callback';
if (new URL(redirectUri).pathname !== '/callback') {
  throw new Error('redirect_uri path must be /callback');
}

Type guard

function isCallbackRequest(req: { url?: string; method?: string }): boolean {
  const parsed = new URL(req.url || '', 'http://localhost:4587');
  return parsed.pathname === '/callback' && req.method === 'GET';
}

Try / catch

// Server-side: the 404 is sent as a response, not thrown. Guard the flow instead:
if (!isCallbackRequest(req)) {
  res.writeHead(404);
  res.end('Not found');
  return;
}

Prevention

When it happens

Trigger: The browser hits http://localhost:4587/ without the /callback path, uses a non-GET method, or the OAuth provider redirects to a redirect_uri whose pathname differs from /callback (e.g. trailing slash, different path, or a host/port mismatch).

Common situations: Users manually opening the port in a browser, health-check scanners probing localhost, or a misconfigured redirect URI in the OAuth app registration sending the authorization code to a different pathname.

Related errors


AI-assisted analysis of dubinc/dub@f216b94a24 (2026-08-31). Data as JSON: /api/errors/5f7a11bcd22e21c8. Report an issue: GitHub.