infiniflow/ragflow · critical · CredentialExpiredError
GitHub credential appears to be invalid or expired (HTTP 401
Error message
GitHub credential appears to be invalid or expired (HTTP 401).
What it means
CredentialExpiredError raised in the GithubException handler for HTTP 401. GitHub returns 401 when the token is bad, revoked, or expired, so the connector maps it to a credential-lifetime error rather than a config error, letting the system mark the credential for re-authentication.
Source
Thrown at common/data_source/github/connector.py:742
"authorizing-a-personal-access-token-for-use-with-saml-single-sign-on"
)
raise ConnectorValidationError(
f"Your GitHub token is missing authorization to access the `{self.repo_owner}` organization. Please follow the guide to authorize your token: {SSO_GUIDE_LINK}"
)
# If not an org, try as a user
user = self.github_client.get_user(self.repo_owner)
# Check if we can access any repos
total_count = user.get_repos().totalCount
if total_count == 0:
raise ConnectorValidationError(f"Found no repos for user: {self.repo_owner}. Does the credential have the right scopes?")
except RateLimitExceededException:
raise UnexpectedValidationError("Validation failed due to GitHub rate-limits being exceeded. Please try again later.")
except GithubException as e:
if e.status == 401:
raise CredentialExpiredError("GitHub credential appears to be invalid or expired (HTTP 401).")
elif e.status == 403:
raise InsufficientPermissionsError("Your GitHub token does not have sufficient permissions for this repository (HTTP 403).")
elif e.status == 404:
if self.repositories:
if "," in self.repositories:
raise ConnectorValidationError(f"None of the specified GitHub repositories could be found for owner: {self.repo_owner}")
else:
raise ConnectorValidationError(f"GitHub repository not found with name: {self.repo_owner}/{self.repositories}")
else:
raise ConnectorValidationError(f"GitHub user or organization not found: {self.repo_owner}")
else:
raise ConnectorValidationError(f"Unexpected GitHub error (status={e.status}): {e.data}")
except Exception as exc:
raise Exception(f"Unexpected error during GitHub settings validation: {exc}")
def validate_checkpoint_json(self, checkpoint_json: str) -> GithubConnectorCheckpoint:
return GithubConnectorCheckpoint.model_validate_json(checkpoint_json)View on GitHub (pinned to 554fb1133a)
Solutions
- Generate a new access token and re-save the credential.
- If using a GitHub App, ensure token refresh logic runs (installation tokens expire hourly).
- Re-run validate_connector_settings() after updating to confirm a clean pass.
Defensive patterns
Strategy: try-catch
Try / catch
try:
connector.validate_connector_settings()
except CredentialExpiredError:
mark_credential_for_reauth(connector) # prompt user; do not auto-retry Prevention
- Rotate tokens before org-enforced expiration dates (set a renewal reminder for 90-day PATs).
- For GitHub Apps, implement installation-token refresh (1h lifetime) instead of storing static tokens.
When it happens
Trigger: Any API probe in validate_connector_settings() (get_repo, get_contents, get_organization, get_user) returns 401 Bad credentials — e.g. deleted/rotated PAT or expired GitHub App token.
Common situations: User regenerated their PAT after saving it; org enforced token expiration (90-day policies) and it lapsed; GitHub App installation token past 1 hour; trailing whitespace/format corruption of the stored token.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- main() must be defined or exported.
- Failed to delete memory
- Failed to update memory
- UCloud Agent Sandbox authentication failed: check the API ke
- Bitbucket
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/e5244a0514d31622.
Report an issue: GitHub.