elsa-workflows/elsa-core · error · HubException
Access denied.
Error message
Access denied.
What it means
Elsa's OpenTelemetry SignalR hub throws this HubException when a connecting client is not authenticated or lacks the ReadOpenTelemetry permission, as checked by EnsureCanReadOpenTelemetry before subscribing to live OpenTelemetry streams. The library guards telemetry data behind the shared PermissionEvaluator so only authorized users can read it.
Solutions
- Ensure the SignalR client supplies a valid access token via AccessTokenFactory or cookie auth before starting the connection.
- Grant the user/role the ReadOpenTelemetry permission in your Elsa permission configuration.
- Verify claims are populated by your auth middleware (check Context.User.IsAuthenticated server-side).
- Wrap hub invocation in try-catch and surface a clear 'sign in required' message to the UI.
Example fix
// before
await connection.start();
await connection.invoke('SubscribeAsync');
// after
const connection = new HubConnectionBuilder()
.withUrl('/hubs/opentelemetry', { accessTokenFactory: () => getToken() })
.build();
await connection.start();
await connection.invoke('SubscribeAsync'); Defensive patterns
Strategy: try-catch
Validate before calling
const isAuthenticated = user?.identity?.isAuthenticated === true; const canRead = isAuthenticated && user.permissions.includes('OpenTelemetry.Read'); if (!canRead) throw new Error('Sign in with OpenTelemetry read permission before subscribing.'); Type guard
function canReadTelemetry(user) { return Boolean(user?.identity?.isAuthenticated) && Array.isArray(user?.permissions) && user.permissions.includes('OpenTelemetry.Read'); } Try / catch
try { await connection.invoke('SubscribeAsync'); } catch (e) { if (e?.message === 'Access denied.') redirectToLogin(); else throw e; } Prevention
- Always pass an access token to the SignalR connection via accessTokenFactory.
- Check the user's permission set before opening telemetry hubs.
- Keep permission grants (ReadOpenTelemetry) in your deployment configuration review checklist.
- Handle the 'Access denied.' HubException explicitly to guide users to sign in.
When it happens
Trigger: Calling SubscribeAsync on the OpenTelemetryHub while Context.User is null or unauthenticated, or while the authenticated user has no ReadOpenTelemetry permission per PermissionEvaluator.Shared.
Common situations: Forgetting to send the auth token with the SignalR handshake (accessTokenFactory missing), the user's roles/claims not granting the OpenTelemetry read permission, or anonymous access to the hub endpoint after upgrading Elsa where authorization was newly enforced.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Access denied.
- The OpenTelemetry filter 'from' timestamp must be earlier…
- Access denied.
- ' ' is not a well-formed permission. Expected ' : '.
- Cannot overwrite an AI conversation that belongs to another…
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/836839050bbd39c2.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Diagnostics.OpenTelemetry/RealTime/OpenTelemetryHub.cs:48
await base.OnDisconnectedAsync(exception).ConfigureAwait(false);
}
private static OpenTelemetryTraceFilter ValidateFilter(OpenTelemetryTraceFilter? filter)
{
filter ??= new();
if (filter.From is { } from && filter.To is { } to && from > to)
throw new HubException("The OpenTelemetry filter 'from' timestamp must be earlier than or equal to 'to'.");
return filter;
}
private void EnsureCanReadOpenTelemetry()
{
var user = Context.User;
if (user?.Identity?.IsAuthenticated != true || !PermissionEvaluator.Shared.HasPermission(user, ReadOpenTelemetry))
throw new HubException("Access denied.");
}
}
View on GitHub (pinned to fe9217bdfa)