Skip to content

エラーカタログ

OP は閉じたカタログからしかエラーを返しません。fmt.Errorf の文字列が通信路上に漏れることはなく、すべての errorop.Error (構築時 / 設定エラー)か、エンドポイント内部のコード定数(リクエスト処理エラー)から構築されます。

このページは両方を網羅した一覧です。

エラーの形

通信路上に出るエラーはすべて、OAuth 2.0 / OIDC の規約に従います:

json
{
  "error": "invalid_request",
  "error_description": "client_id is required"
}
  • error は、下のカタログのいずれかです。機械可読で、ローカライズはせず、ラップもしません。
  • error_description は運用者向けの短いヒントです。トークン、ユーザの生入力、スタックトレースを含みません。

ブラウザ向けエンドポイント(/authorize/end_session)では、同じコードが以下のいずれかに現れます:

  • redirect_uristate を検証できた場合は、redirect 上の error パラメータ(query / fragment)。
  • 安全な redirect 先が無い場合は、HTML エラーページの DOM (<div id="op-error" data-code="..." data-description="...">)。

プログラム的に判別する

go
import "errors"

if errors.Is(err, op.ErrIssuerRequired) { /* 設定時エラー */ }

if op.IsClientError(err) { /* 4xx 系 */ }
if op.IsServerError(err) { /* 5xx 系 */ }

sentinel 比較は Go の errors.Is の既定どおり、ポインタ同一性で判定します。同じ OAuth コードを共有する別の sentinel が存在し得るので(たとえば、複数の configuration_error)、両者は同じ意味になるとは限りません。

構築時エラー(op.New)

コンストラクタが返します。OP は起動しません。

Sentinelコード発生条件
op.ErrIssuerRequiredconfiguration_errorWithIssuer を渡していない
op.ErrIssuerInvalidconfiguration_errorissuer が absolute https でない、または query / fragment を持つ
op.ErrStoreRequiredconfiguration_errorWithStore を渡していない
op.ErrKeysetRequiredconfiguration_errorWithKeyset を渡していない、または空
op.ErrCookieKeysRequiredconfiguration_errorauthorization_code grant が有効なのに WithCookieKey / WithCookieKeys を渡していない
op.ErrDynamicRegistrationDisabledconfiguration_errorWithDynamicRegistration 無しで Provider.IssueInitialAccessToken を呼んだ

他の設定エラー

プロファイルとオプションの衝突(たとえば WithProfile(FAPI2Baseline)WithAccessTokenFormat(Opaque) の併用)は *op.Error を返し、Code = configuration_error、description に衝突したオプション名が入ります。これらは事前定義された sentinel ではないので、op.IsServerError を使うか、.Code を直接見て判別してください。

Authorize エンドポイント(/authorize)

ブラウザ経由のエンドポイントです。redirect_uri を検証できれば redirect で、できなければ HTML エラーページでユーザに到達します。

コード仕様典型的な原因
invalid_requestOIDC Core §3.1.2.6パラメータ欠落、PKCE 不正、state がサイズ上限超過
invalid_request_objectRFC 9101 §6.1JAR JWS の検証失敗、alg 非許可、有効期限切れ
invalid_request_uriRFC 9101 §6.1 / RFC 9126 §2.2PAR の request_uri がすでに消費済み、または期限切れ
invalid_scopeOIDC Core §3.1.2.6要求された scope がカタログに存在しない
unsupported_response_typeOIDC Core §3.1.2.6response_typecode 以外(Implicit / Hybrid は拒否)
unsupported_response_modeOAuth 2.1未対応の response_mode
login_requiredOIDC Core §3.1.2.6prompt=none だがアクティブセッションが無い
consent_requiredOIDC Core §3.1.2.6prompt=none だが consent が無い
interaction_requiredOIDC Core §3.1.2.6prompt=none だが UI が必要
account_selection_requiredOIDC Core §3.1.2.6prompt=none で複数のセッションがある
access_deniedOIDC Core §3.1.2.6ユーザが consent / login で取り消した
server_errorOIDC Core §3.1.2.6内部障害

redirect URI 不一致は特殊

invalid_request: redirect_uri does not match a registered URI は、authorize エラーのうち唯一 redirect させずに返すケースです。URL 自体が信頼できないので、ユーザは HTML エラーページに到達します。FAQ § よくあるエラー を参照。

Token エンドポイント(/token)

JSON 応答です。RFC 6749 §5.2 + RFC 9449(DPoP)。

コードHTTP発生条件
invalid_request400grant の body の不正、パラメータ欠落
invalid_grant400code の有効期限切れ / 消費済み、refresh token がローテーション猶予を超過、PKCE verifier 不一致
invalid_client401クライアント認証失敗(クレデンシャル無し、secret 違い、private_key_jwt / mTLS 証明書不正)
unauthorized_client400このクライアントは当該 grant を許可されていない
unsupported_grant_type400WithGrants で有効化されていない grant
invalid_scope400refresh が元より広い scope を要求している
use_dpop_nonce400DPoP §8 のサーバ nonce が必要。クライアントは DPoP-Nonce を載せて再送する
server_error500内部障害

401 invalid_client は常に WWW-Authenticate: Basic realm="<issuer>" (/userinfo では Bearer realm=...)を載せます(RFC 6749 §5.2)。

UserInfo エンドポイント(/userinfo)

bearer 検証を行います。RFC 6750 §3.1 + RFC 9449。

コードHTTP発生条件
invalid_token401bearer 欠落、期限切れ、失効済み、alg 不一致
invalid_dpop_proof401DPoP proof JWS の不正、再送、cnf.jkt 不一致
use_dpop_nonce401DPoP §8 のサーバ nonce が必要
insufficient_scope403要求された claim に対して scope が不足

Introspection / Revocation(/introspect/revoke)

RFC 7662 / RFC 7009。/token と同じクライアント認証コードの集合を使います。

コードHTTP発生条件
invalid_request400token パラメータ欠落
invalid_client401クライアント認証失敗
unsupported_token_type400/revoke のみ — 失効不可なトークンタイプ
server_error500内部障害

PAR エンドポイント(/par)

RFC 9126。

コードHTTP発生条件
invalid_request400PAR ボディ内の authorize パラメータが不正
invalid_request_object400(request パラメータ併用時)JAR の署名検証失敗
invalid_client401クライアント認証失敗

Dynamic Client Registration(/register/register/{client_id})

RFC 7591 / RFC 7592。

コードHTTP発生条件
invalid_request400必須メタデータの欠落
invalid_token401IAT / RAT bearer の欠落 / 期限切れ
invalid_client_metadata400メタデータがポリシーに反する(たとえば、未対応の response_types)
invalid_redirect_uri400redirect URI の形式が拒否対象(loopback ワイルドカード、fragment など)
invalid_software_statement400software statement の JWS 検証失敗
server_error500内部障害

End-session(/end_session)

OIDC RP-Initiated Logout 1.0。ブラウザ向けです。post_logout_redirect_uri への redirect か、HTML エラーページでユーザに到達します。

コード発生条件
invalid_requestid_token_hint の不正、client_id 不一致
invalid_request_uri(JAR 形式の logout request 利用時)request_uri の期限切れ

クラス単位での dispatch

各コードを個別に switch するのではなく、述語を使うのが推奨です:

go
switch {
case errors.Is(err, op.ErrIssuerRequired):
    // 起動時に直すべき設定エラー
case op.IsClientError(err):
    // 4xx — info ログで十分。アラートはしない
case op.IsServerError(err):
    // 5xx — 発生率にアラートを張る
}

このリストの裏取り

sh
git clone https://github.com/libraz/go-oidc-provider.git
cd go-oidc-provider
grep -rhE '"[a-z_]+_[a-z_]+"' internal/*/error*.go \
  | grep -oE '"[a-z_]+_[a-z_]+"' | sort -u

出力は、各エンドポイントが返し得るすべての通信路上のコードの和集合です。このページではそれをエンドポイントごとにまとめ、各仕様参照を添えています。