Dokploy/dokploy · error · Error
Failed to refresh token: ${response.statusText}
Error message
Failed to refresh token: ${response.statusText} What it means
Thrown when GitLab's OAuth token refresh endpoint returns a non-2xx response. refreshGitlabToken POSTs grant_type=refresh_token with the provider's applicationId/secret; any HTTP failure (400 invalid_grant, 401 bad client credentials, network proxy error) surfaces as this generic statusText message.
Source
Thrown at packages/server/src/utils/providers/gitlab.ts:42
}
// Use internal URL for token refresh when GitLab is on same instance as Dokploy
const baseUrl = gitlabProvider.gitlabInternalUrl || gitlabProvider.gitlabUrl;
const response = await fetch(`${baseUrl}/oauth/token`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: gitlabProvider.refreshToken as string,
client_id: gitlabProvider.applicationId as string,
client_secret: gitlabProvider.secret as string,
}),
});
if (!response.ok) {
throw new Error(`Failed to refresh token: ${response.statusText}`);
}
const data = await response.json();
const expiresAt = data.expires_in
? Math.floor(Date.now() / 1000) + data.expires_in
: null;
await updateGitlab(gitlabProviderId, {
accessToken: data.access_token,
refreshToken: data.refresh_token,
expiresAt,
});
return data;
};
export const haveGitlabRequirements = (gitlabProvider: Gitlab) => {
return !!(gitlabProvider?.accessToken && gitlabProvider?.refreshToken);View on GitHub (pinned to 546686ea35)
Solutions
- Re-authenticate the GitLab provider (re-do the OAuth flow) to get a fresh refresh token
- Verify the GitLab OAuth application ID and secret stored on the provider match the GitLab app
- Log response.status and the JSON body (error/error_description) instead of statusText to see the real cause
- Check network/DNS/TLS reachability of the GitLab instance from the server
Example fix
// before
if (!response.ok) {
throw new Error(`Failed to refresh token: ${response.statusText}`);
}
// after
if (!response.ok) {
const body = await response.text();
throw new Error(`Failed to refresh token: ${response.status} ${response.statusText} ${body}`);
} Defensive patterns
Strategy: retry
Validate before calling
const provider = await findGitlabById(gitlabId);
if (!provider?.refreshToken) throw new Error('Re-authenticate the GitLab provider'); Type guard
const canRefresh = (p: unknown): p is { refreshToken: string; applicationId: string; secret: string } =>
typeof p === 'object' && p !== null &&
typeof (p as any).refreshToken === 'string' && (p as any).refreshToken.length > 0; Try / catch
try {
await refreshGitlabToken(gitlabId);
} catch (e) {
// token revoked — force re-auth flow, don't retry in a loop
throw new Error(`Re-authentication required: ${e instanceof Error ? e.message : e}`);
} Prevention
- Re-authenticate the provider when refresh fails rather than retrying blindly
- Keep the OAuth app secret in sync with GitLab
- Log response bodies on refresh failure for diagnosability
When it happens
Trigger: Refresh token expired or revoked (user revoked app access in GitLab), wrong applicationId/secret for the OAuth app, GitLab instance unreachable behind a proxy, or redirect/app configuration mismatch on a self-hosted GitLab.
Common situations: Long-lived Dokploy install where the stored GitLab refresh token expired; rotating the GitLab OAuth app secret without updating the provider; self-hosted GitLab with certificate or network issues.
Related errors
- Failed to fetch branches: ${branchesResponse.statusText}
- BAD_REQUEST
- BAD_REQUEST
- Error ${response.status}: ${response.statusText}. Please ver
- Gitlab provider not found
AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27).
Data as JSON: /api/errors/168faf807efdbc7b.
Report an issue: GitHub.