opf/openproject · error · Import::JiraClient::ApiError
Jira API returned a 401 error. Your authentication token may
Error message
Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
What it means
Import::JiraClient#handle_response turns every non-2xx HTTP response into an ApiError whose message comes from the locale key admin.jira.client.401_error. A 401 from Jira means the Bearer token was rejected: expired, revoked/regenerated, wrong value, or the token owner is not a Jira administrator as required by the importer.
Source
Thrown at app/services/import/jira_client.rb:309
params:,
http_options: HTTP_OPTIONS
)
rescue SsrfFilter::PrivateIPAddress
raise SsrfError, I18n.t("admin.jira.client.ssrf_blocked")
rescue SsrfFilter::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e
raise ConnectionError, I18n.t("admin.jira.client.connection_error", message: e.message)
rescue OpenSSL::SSL::SSLError => e
raise ConnectionError, I18n.t("admin.jira.client.ssl_error", message: e.message)
rescue Timeout::Error => e
raise ConnectionError, I18n.t("admin.jira.client.connection_timeout", message: e.message)
end
def handle_response(response)
status = response.code.to_i
if response.is_a?(Net::HTTPSuccess)
parse_json(response)
else
raise ApiError.new(
I18n.t("admin.jira.client.#{status}_error", status:, default: :"admin.jira.client.api_error"),
status:,
response_body: response.body.to_s
)
end
end
def parse_json(response)
JSON.parse(response.body)
rescue JSON::ParserError => e
raise ParseError, I18n.t("admin.jira.client.parse_error", message: e.message)
end
end
end
View on GitHub (pinned to d9742c43f3)
Solutions
- Create a fresh API token in Jira for an administrator account, update it in Admin → Import → Jira settings, save and run the test connection.
- Confirm the token owner actually holds Jira administrator permission (the importer calls /rest/api/2/mypermissions which requires it).
- If the error appears mid-run after working before, the token was likely revoked/rotated — re-enter it and restart the import run.
Example fix
# before
begin
client.mypermissions
rescue Import::JiraClient::ApiError => e
puts e.message
end
# after
begin
client.mypermissions
rescue Import::JiraClient::ApiError => e
if e.status == 401
raise 'Re-enter the Jira API token (expired or revoked) in admin settings'
end
raise
end Defensive patterns
Strategy: try-catch
Try / catch
begin client.mypermissions rescue Import::JiraClient::ApiError => e raise CredentialsExpired, 're-enter Jira API token' if e.status == 401 raise end
Prevention
- Treat 401 as a terminal condition for the run: stop, surface a re-credential form, do not retry with the same token.
- Run the connection test before each import run to catch rotated/expired tokens up front.
- Use a dedicated, administrator-owned Jira token so unrelated permission changes don't break it.
When it happens
Trigger: Any JiraClient request (mypermissions, project/issue fetching during a run, or the admin 'test connection') after the API token was revoked or regenerated in Jira, or after the owning Jira user lost admin rights.
Common situations: Atlassian API tokens expire or get rotated; someone regenerated the token in Jira while an import run was queued; token pasted with surrounding whitespace; the settings were saved with an empty token field so a stale/blank header is sent.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid API token. Please check your credentials in the conf
- A Jira import run cannot be removed while it is running
- Jira API returned a 429 error. It means token owner has been
- Jira API returned error status %{status}
- You are trying to import a project with an already used iden
AI-assisted analysis of opf/openproject@d9742c43f3 (2026-08-21).
Data as JSON: /api/errors/848e56841353084f.
Report an issue: GitHub.