We’re experiencing intermittent failures with our Flow Builder automation that triggers REST API callouts to an external system. The flow runs fine when tested manually, but when triggered by record updates, we get ‘INVALID_SESSION_ID: Session expired or invalid’ errors about 40% of the time.
Our HTTP Callout action configuration uses a Named Credential with OAuth 2.0 authentication. Here’s the error we’re seeing:
System.CalloutException: INVALID_SESSION_ID
at Flow.Account_Update_External_System
HTTP Status: 401 Unauthorized
The Named Credential was set up following documentation, and we can see successful authentication in the logs when it works. The inconsistency is what’s puzzling - same flow, same credentials, different results. We’ve checked session timeout settings in our external system and they’re set to 2 hours, which should be more than adequate.
Has anyone dealt with session management issues in Flow HTTP Callouts? We’re on Summer '24 and this is blocking our account synchronization process.
I’ve solved this exact issue multiple times. The problem is definitely your authentication model combined with how flows handle callout context. Here’s the comprehensive solution:
1. Flow HTTP Callout Configuration - Switch to Named Principal:
Per-user credentials in automated flows create session context mismatches. The flow runs in system context but tries to authenticate with the triggering user’s session, which may be expired or unavailable. Convert your Named Credential to use Named Principal authentication with a dedicated integration user.
In Setup → Named Credentials → Edit your credential:
- Identity Type: Named Principal (not Per User)
- Authentication Protocol: OAuth 2.0
- Generate Authorization Header: Enabled
- Allow Merge Fields in HTTP Header: Enabled
2. Session Management in Flows - Implement Proper Error Handling:
Flows don’t automatically retry failed callouts. Add fault path handling to your HTTP Callout action:
// In Flow Builder:
HTTP Callout Action → Add Fault Path
If $Flow.FaultMessage contains 'INVALID_SESSION'
Store record ID in custom object CalloutQueue__c
Set retry flag and timestamp
Then create a scheduled flow that processes the queue every 15 minutes with fresh authentication context.
3. Named Credential Usage - Token Refresh Strategy:
The 40% failure rate suggests bulk operations where multiple flow instances compete for token refresh. Implement a custom Apex invocable method that handles this properly:
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:YourNamedCredential/api/endpoint');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
Using the ‘callout:’ prefix with Named Credentials ensures Salesforce manages the entire OAuth flow including automatic token refresh.
Additional Recommendations:
-
Avoid Synchronous Callouts in Triggers: If your flow is trigger-based, consider using Platform Events to decouple the callout from the transaction. This prevents governor limit issues and provides better session isolation.
-
Monitor Token Lifecycle: Set up a custom setting to track token refresh timestamps. If you see refresh attempts during your failure windows, that confirms the session management hypothesis.
-
External System Configuration: Verify your external system’s OAuth settings allow token refresh without re-authentication. Some systems require explicit refresh token grants in the OAuth scope.
-
Implement Circuit Breaker Pattern: If failures persist, add logic to temporarily disable callouts after repeated failures, then gradually retry. This prevents cascade failures.
Testing Strategy:
After implementing these changes:
- Test with single record updates (should work 100%)
- Test with bulk updates of 50+ records (the real validation)
- Monitor debug logs for ‘OAUTH_TOKEN_REFRESH’ entries
- Check external system logs for authentication patterns
The combination of Named Principal authentication and proper error handling should eliminate your intermittent failures. The key insight is that flows in automated contexts need explicit session management that differs from interactive user sessions.
One more consideration - check your Connected App settings for the external system. If token timeout is set too aggressively on their end, you’ll see exactly this pattern of intermittent failures.
The 40% failure rate suggests this might be a timing issue with token refresh cycles. When flows fire in rapid succession from bulk updates, they might all try to use the same token before it’s refreshed. Consider implementing a queueable approach instead of direct callouts from flows. You could have the flow create a platform event, then use an async Apex trigger to handle the actual API call. This gives you better control over retry logic and session management. Also check if your Named Credential has ‘Allow Merge Fields in HTTP Header’ enabled - sometimes credential context gets lost in automated flows.
Another thing to watch for: if your flow has multiple HTTP Callout actions in sequence, each one establishes its own session context. The second or third callout might fail if there’s any delay in token propagation. I’d recommend consolidating multiple callouts into a single invocable Apex method where you can implement proper error handling and retry logic with exponential backoff.
Thanks for the suggestions. I checked and we are using per-user authentication, which might be the culprit. The Named Credential does have ‘Generate Authorization Header’ enabled. I’m going to test switching to named principal with a dedicated integration user account.
I’ve seen similar behavior. The issue is often that Named Credentials with OAuth 2.0 don’t always refresh tokens properly in flow context. When the flow is triggered by DML operations, it might be using a cached session that’s already expired. Check if your Named Credential is set to ‘Generate Authorization Header’ - this should be enabled for proper token management.
Are you using per-user or named principal authentication? Per-user credentials can cause this exact issue because the flow runs in system context but tries to use the triggering user’s session. Switch to named principal with a dedicated integration user. Also verify that your external system isn’t invalidating tokens when it sees multiple concurrent requests - I’ve seen rate limiting disguised as session errors.