本文へスキップ
ecdsa.com
PHP streams (file_get_contents, fopen, stream_socket_client, SoapClient, mail libraries)PHP

エラーメッセージ

SSL operation failed with code 1. OpenSSL Error messages:

別の表記

  • Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:

PHP はこの警告を 2 行で出力します。「SSL operation failed with code 1. OpenSSL Error messages:」の後に、1 つまたは複数の OpenSSL のエラーが続きます。OpenSSL 1.1.1 のビルドでは、代わりに「error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed」と表示されます。

PHP streams (file_get_contents, fopen, stream_socket_client, SoapClient, mail libraries) — openssl stream wrapper

このエラーの意味

PHP のストリーム(file_get_contents、fopen、SoapClient、stream_socket_client、およびこれらを基盤とするメールや FTP のライブラリ)で TLS ハンドシェイクが失敗しました。コード 1 は OpenSSL のエラーコード SSL_ERROR_SSL で、実際の理由は次の行に示されます。最も多いのは「error:0A000086:SSL routines::certificate verify failed」です。その後に PHP が「Failed to enable crypto」と「Failed to open stream: operation failed」を追加しますが、これらは原因ではなく結果です。

発生する理由

修正方法

  1. 1.

    続く OpenSSL の行を確認する

    「certificate verify failed」は信頼関係か日付の問題を示し、プロトコルのエラーはサーバーの TLS 設定の問題を示します。

    text
    Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
    error:0A000086:SSL routines::certificate verify failed      <- trust/chain/date problem
    Warning: file_get_contents(): Failed to enable crypto       <- consequence, not the cause
  2. 2.

    openssl.cafile を設定する

    PHP のストリームは openssl.cafile(または openssl.capath)を使い、ext-curl は curl.cainfo を使います。そのため、両方を設定してください。

    ini
    ; php.ini — CA bundle for PHP streams (file_get_contents, SoapClient, stream_socket_client)
    openssl.cafile = "/etc/ssl/certs/ca-certificates.crt"
  3. 3.

    1 つのリクエストだけに CA を渡す

    ssl.cafile を指定したストリームコンテキストを使うと、ほかの通信の検証を弱めることなく、プライベート CA を信頼できます。

    php
    // One request with a private CA; verification stays on
    $context = stream_context_create(['ssl' => [
        'cafile' => '/etc/ssl/private-ca/corp-root-ca.pem',
        'verify_peer' => true,
        'verify_peer_name' => true,
    ]]);
    $body = file_get_contents('https://api.example.com/', false, $context);

関連するエラー

署名エラーデータベースをすべて見る