Why doesn't Next.js Server Action throw an error when IAP returns 401 Unauthorized on Cloud Run?
22:13 09 Nov 2025

I'm deploying a Next.js 14 app on Google Cloud Run, protected by IAP (Identity-Aware Proxy) and fronted by a Load Balancer. Everything works fine when the user is logged in with a Google account. However, after a period of inactivity (when the Google session expires), calling a Server Action results in a 401 Unauthorized response from IAP — but no error is thrown in the client-side code, even when wrapped in a try/catch.

Working scenario:

  • User logs in via Google.
  • Clicks a button that triggers a Server Action.
  • Server Action executes successfully.

Broken scenario:

  • User session expires (e.g., after being idle for a while).
  • User clicks the same button.
  • The Server Action silently fails — no error is caught, and the return value is undefined.

Example code:

'use client';

import { myServerAction } from './actions';

export default function MyComponent() {
  const handleClick = async () => {
    try {
      const result = await myServerAction();
      console.log('Result:', result);
    } catch (err) {
      console.error('Caught error:', err); // This never runs
    }
  };

  return ;
}
'use server';

export async function myServerAction() {
  // Some logic here
  return 'Hello from server';
}

Observations:

  • When session is valid: result is "Hello from server".
  • When session is expired: result is undefined, and no error is caught.
  • IAP logs show a 401 Unauthorized response.

Questions:

  1. Why doesn't Next.js throw an error when the Server Action fails due to IAP 401?
  2. Is there a way to detect this failure on the client side?
  3. What is the recommended approach to handle session expiration when using Server Actions with IAP?
  4. Should I wrap Server Actions with a custom fetch layer instead?
next.js in-app-purchase