All Docs
FeaturesMaking Tax DigitalUpdated March 11, 2026

Bug Fix: HMRC OAuth Callback Now Requires a Valid NINO

Bug Fix: HMRC OAuth Callback Now Requires a Valid NINO

Release: v1.0.425
Severity: Medium
Status: Fixed


What Happened

A bug was identified in the HMRC OAuth connection flow that could result in credentials being stored with an empty National Insurance Number (NINO), and business details never being retrieved from HMRC — all without any error being surfaced to the user.

This affected users who:

  1. Clicked Skip when prompted for their NINO during onboarding, and
  2. Then proceeded to connect their HMRC account from the HMRC page.

Root Cause

The HMRC authorise route (/api/hmrc/authorise/route.ts) encrypts the user's NINO and embeds it in the OAuth state parameter before redirecting to HMRC. When the OAuth flow completes and HMRC redirects back to the callback route (/api/hmrc/callback/route.ts), the callback decrypts this state and uses the NINO in two subsequent calls:

// In /api/hmrc/callback/route.ts
const encryptedNino = Buffer.from(encryptedNinoB64, 'base64url').toString('utf8');
niNumber = await ninoCipher.decrypt(encryptedNino);

// ...

await upsertCredentials({ userId, orgId, niNumber, tokens });
await fetchBusinessDetails(tokens.access_token, niNumber);

If the user had no NINO set at the time they initiated OAuth, niNumber would be an empty string (''). The code did not guard against this case:

  • upsertCredentials stored the empty string into the credentials record.
  • fetchBusinessDetails forwarded the empty string to the HMRC API, which responded with a 400 or 422 error. This error was caught internally and treated as non-fatal, so execution continued and the callback returned a success response to the user.

Impact

Users affected by this bug would see their HMRC connection appear successful, but:

  • Their stored credentials would have an empty niNumber.
  • Their HMRC business details (including Business ID required for submissions) would not be fetched or stored.
  • Subsequent quarterly submissions would fail, as a valid NINO is required by HMRC's MTD ITSA API at submission time.

The failure at submission time would be the first indication to the user that something had gone wrong — with no clear trace back to the original OAuth connection issue.


The Fix

The callback route now validates the decrypted NINO before proceeding with any HMRC API calls or credential storage. If the NINO is empty or absent, the callback returns an explicit error response and does not store credentials.

This ensures:

  • No credentials are saved in an invalid state.
  • Users receive a clear, actionable error message explaining that their NINO must be set before connecting to HMRC.
  • The silent data corruption path is fully closed.

Action Required

If you connected to HMRC before setting your NINO

Your stored credentials may be affected. To resolve this:

  1. Go to Settings → Profile and add your National Insurance Number.
  2. Navigate to the HMRC page.
  3. Disconnect your existing HMRC connection (if applicable).
  4. Click Connect to HMRC and complete the OAuth flow again.

Your credentials will be saved correctly and your business details will be fetched from HMRC.

For new connections

No action required. The fix is applied automatically. If you attempt to connect to HMRC without a NINO set, you will now see a clear prompt to add your NINO first.


Affected Components

ComponentFile
HMRC Authorise Routesrc/app/api/hmrc/authorise/route.ts
HMRC Callback Routesrc/app/api/hmrc/callback/route.ts

Related