{"record":{"id":"43c0b9d56fa2fa43","repo":"gitlabhq/gitlabhq","slug":"failed-to-return-the-key","errorCode":null,"errorMessage":"Failed to return the key","messagePattern":"Failed to return the key","errorType":"exception","errorClass":"KeysFinder::InvalidFingerprint","httpStatus":400,"severity":"error","filePath":"app/finders/keys_finder.rb","lineNumber":78,"sourceCode":"\n    keys.created_after(params[:created_after])\n  end\n\n  def by_expires_before(keys)\n    return keys unless params[:expires_before]\n\n    keys.expires_before(params[:expires_before])\n  end\n\n  def by_expires_after(keys)\n    return keys unless params[:expires_after]\n\n    keys.expires_after(params[:expires_after])\n  end\n\n  def by_fingerprint(keys)\n    return keys unless params[:fingerprint].present?\n    raise InvalidFingerprint unless valid_fingerprint_param?\n\n    keys.find_by(fingerprint_query) # rubocop:disable CodeReuse/ActiveRecord -- find_by needed for fingerprint lookup\n  end\n\n  def valid_fingerprint_param?\n    return Base64.decode64(fingerprint).length == 32 if fingerprint_type == \"sha256\"\n\n    return false if Gitlab::FIPS.enabled?\n\n    fingerprint =~ /^(\\h{2}:){15}\\h{2}/\n  end\n\n  def fingerprint_query\n    fingerprint_attribute = FINGERPRINT_ATTRIBUTES[fingerprint_type]\n\n    Key.arel_table[fingerprint_attribute].eq(fingerprint)\n  end\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/gitlabhq/gitlabhq/blob/55ee20384a1f55cb0e362dee1d07149613b1b9bf/app/finders/keys_finder.rb#L60-L96","documentation":"KeysFinder#by_fingerprint raises InvalidFingerprint (rendered by the keys API as HTTP 400 'Failed to return the key', lib/api/keys.rb) when the fingerprint parameter fails validation. A SHA256 fingerprint (recognized by its sha256:/SHA256: prefix) must Base64-decode to exactly 32 bytes; an MD5 fingerprint must match 16 colon-separated hex pairs - and MD5 is rejected outright when the instance runs in FIPS mode.","triggerScenarios":"GET /api/v4/keys?fingerprint=<malformed string>; supplying a SHA256 digest in hex (64 hex chars) instead of base64; sending an MD5 (colon-delimited) fingerprint to a FIPS-enabled GitLab; whitespace or truncation from copy-pasting the fingerprint.","commonSituations":"Tools that print fingerprints in hex; older scripts written before SHA256 fingerprints became the default; FIPS-compliant self-managed installations where MD5 lookups silently stopped working; UIs that strip colons from MD5 strings.","solutions":["Use the SHA256 form: the literal prefix sha256: followed by the base64 digest that decodes to 32 bytes - exactly what `ssh-keygen -lf key.pub` prints.","If you must use MD5, ensure the format is exactly 16 lowercase hex pairs separated by colons (aa:bb:...), but prefer migrating to SHA256.","On FIPS instances, switch entirely to SHA256 fingerprints - MD5 lookups cannot work there.","Copy the fingerprint from `GET /keys` output or the user's profile page rather than re-typing it."],"exampleFix":"# before: hex-encoded sha256 digest is not valid\nGET /api/v4/keys?fingerprint=SHA256:1f2e3d4c5b6a...64-hex-chars\n# => 400 Failed to return the key\n\n# after: base64 digest as printed by ssh-keygen -lf\nGET /api/v4/keys?fingerprint=SHA256:H8xP4pCT6mQ0zqF3nJ9yQcVeEr5T5Y+1a2B3c4D5e6F","handlingStrategy":"validation","validationCode":"def fingerprint_ok?(fp)\n  if fp.match?(/sha256:/i)\n    require 'base64'\n    Base64.decode64(fp.sub(/sha256:/i, '')).bytesize == 32\n  else\n    !Gitlab::FIPS.enabled? && fp.match?(/^([0-9a-f]{2}:){15}[0-9a-f]{2}/)\n  end\nend\n\nrender_api_error!('bad fingerprint', 400) unless fingerprint_ok?(params[:fingerprint])","typeGuard":"def valid_sha256_fingerprint?(fp)\n  fp.to_s.start_with?('sha256:', 'SHA256:') &&\n    Base64.decode64(fp.sub(/(sha256:)|(SHA256:)/, '')).bytesize == 32\nend","tryCatchPattern":"begin\n  key = KeysFinder.new(fingerprint: fp).execute\nrescue KeysFinder::InvalidFingerprint\n  render_api_error!('Failed to return the key', 400) # terminal: fix the fingerprint format, do not retry\nend","preventionTips":["Standardize on SHA256 fingerprints produced by ssh-keygen -lf.","Validate format (and FIPS mode) before calling the keys API.","Never reformat fingerprints programmatically - copy them verbatim."],"tags":["gitlab","ssh-keys","fingerprint","validation","fips"],"backgroundTag":"invalid-fingerprint-format","analyzedSha":"55ee20384a1f55cb0e362dee1d07149613b1b9bf","analyzedAt":"2026-08-21T14:22:27.782Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}