روی لپتاپ محل کارتان npm install را اجرا میکنید و فرمان با npm error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY متوقف میشود. رجیستری npm روی همان دستگاه در کروم بیمشکل باز میشود و همکاری که از خانه کار میکند همان بستهها را بدون دردسر نصب میکند. یک اسکریپت Python با CERTIFICATE_VERIFY_FAILED شکست میخورد و git clone از یک مشکل گواهی SSL خبر میدهد. رجیستری هیچ ایرادی ندارد: ابزارهای شما و مرورگرتان به فهرستهای متفاوتی از مراجع صدور گواهی اعتماد دارند.
این راهنما توضیح میدهد کلاینت دقیقاً چه چیزی را بررسی میکند، سه علت را با خطاهایی که روی سرورهای آزمایشی محلی بازتولید کردهایم از هم جدا میکند و راه رفع را برای Python، npm، Git و curl و سپس برای سمت سرور ارائه میدهد.
«unable to get local issuer certificate» یعنی چه؟
یک گواهی TLS نام صاحب خود (subject) و نام مرجع صدور گواهی (CA) را که آن را امضا کرده (issuer) در خود دارد. سرور گواهی خودش را که به آن گواهی برگ (leaf) میگویند، همراه یک یا چند گواهی میانی میفرستد که آن را به یک گواهی ریشه وصل میکنند. گواهیهای ریشه هنگام اتصال فرستاده نمیشوند: هر کلاینت مجموعه ریشههای مورد اعتماد خودش، یعنی مخزن اعتماد، را نگه میدارد و واژه «local» (محلی) در پیام به همین مجموعه اشاره دارد.
این متن خطای شماره 20 در تأیید OpenSSL است: X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY. کلاینت به گواهیای رسیده که صادرکنندهاش را نه میان گواهیهایی که سرور فرستاده پیدا کرده و نه در مخزن خودش. دستدادن TLS پیش از ارسال درخواست شما متوقف میشود.
تأیید زنجیره گواهی چگونه کار میکند؟
- سرور زنجیرهاش را میفرستد. نخست گواهی برگ میآید، هر گواهی بعدی گواهی پیش از خود را امضا میکند و ریشه ممکن است فرستاده نشود، چون کلاینتها آن را از قبل دارند (بخش 4.4.2 از RFC 8446).
- کلاینت گواهی برگ را بررسی میکند: نام باید با میزبان در URL یکی باشد و تاریخها باید معتبر باشند.
- کلاینت صادرکننده هر گواهی را پیدا میکند، آن را میان گواهیهای فرستادهشده میجوید، امضا را بررسی میکند و همین کار را یک سطح بالاتر تکرار میکند.
- بالای زنجیره باید به مخزن اعتماد برسد، یعنی ریشهای که کلاینت از قبل به آن اعتماد دارد باید آن را امضا کرده باشد.
- یک حلقه گمشده دستدادن را متوقف میکند و متن خطا به جایی بستگی دارد که زنجیره در آن قطع شده است.
مخزن اعتماد به ابزار بستگی دارد، نه به دستگاه. Requests از certifi استفاده میکند، بستهای در Python که فهرست ریشههای موزیلا را در خود دارد؛ Node.js در هر نسخه، تصویری از مخزن موزیلا را درون خود کامپایل میکند؛ Git for Windows فایل ca-bundle.crt خودش یا مخزن ویندوز را میخواند. به همین دلیل روی یک لپتاپ، یک برنامه ممکن است شکست بخورد در حالی که برنامه دیگری موفق میشود.
سه پیام خطا، یک خانواده
با OpenSSL یک ریشه، یک میانی و یک برگ ساختیم، سه سرور HTTPS محلی راه انداختیم که بخشهای متفاوتی از زنجیره را میفرستند و آنها را روی ویندوز 11 از Python 3.13.9 (Requests 2.34.2)، Node.js 24.11.1 (npm 11.6.2)، curl 8.21.0 و Git 2.55 با OpenSSL فراخواندیم. هیچکدام از ابزارها ریشه ما را نمیشناخت.
| آنچه سرور فرستاد | Python (ssl، Requests) | Node.js و npm | curl و Git (OpenSSL) |
|---|---|---|---|
| برگ + میانی | unable to get local issuer certificate | UNABLE_TO_GET_ISSUER_CERT_LOCALLY | unable to get local issuer certificate (20) |
| فقط برگ | unable to get local issuer certificate | UNABLE_TO_VERIFY_LEAF_SIGNATURE | unable to get local issuer certificate (20) |
| برگ + میانی + ریشه | self-signed certificate in certificate chain | SELF_SIGNED_CERT_IN_CHAIN | self-signed certificate in certificate chain (19) |
Python و curl برای گواهی میانی گمشده و ریشه ناشناخته از یک عبارت استفاده میکنند، پس فقط خود زنجیره نشان میدهد کدام طرف را باید اصلاح کرد. سطر سوم همان مشکل است، با این تفاوت که ریشه هم فرستاده شده: سرور، یا پروکسیای در میانه راه، ریشهای فرستاده که ابزار شما به آن اعتماد ندارد.
سه علت پشت این خطا
1. سرور گواهی میانی خود را نمیفرستد
مدیر سرور فقط گواهی برگ را نصب کرده است، پس هر کلاینتی که گواهی میانی را نداشته باشد، روی هر شبکهای شکست میخورد. مرورگرها اغلب این مشکل را پنهان میکنند: به توضیح موزیلا، فایرفاکس گواهیهای میانی شناختهشده را از پیش همراه خود دارد و مرورگرهای دیگر گواهی گمشده را در پسزمینه دانلود میکنند. Python، Node.js، curl و Git هیچکدام از این دو کار را نمیکنند، پس «در کروم کار میکند» چیزی را ثابت نمیکند.
2. پروکسی یا آنتیویروسی که TLS را بازرسی میکند ترافیک را دوباره امضا میکند
گیتویهای وب سازمانی، آنتیویروسهایی که اسکن HTTPS دارند و ابزارهای اشکالزدایی مانند mitmproxy، Charles و Fiddler اتصال رمزگذاریشده را باز میکنند و برای سایت گواهی تازهای ارائه میدهند که با ریشه خودشان امضا شده است. تیم IT این ریشه را در مخزن سیستم لپتاپهای مدیریتشده نصب میکند، پس مرورگرها آن را میپذیرند؛ اما ابزارهایی که فهرست خودشان را دارند نمیپذیرند. نشانهها: خطا روی شبکه دفتر یا VPN ظاهر میشود، نه در خانه، و تقریباً همه سایتها را درگیر میکند. اگر خودتان چنین ابزاری را اجرا میکنید، مرحله گواهی ریشه آن در نوشته پروکسی MITM چیست؟ آمده است.
3. ابزار شما به فهرستی جدا از فهرست سیستم اعتماد دارد
فایلهای CA در Requests، Node.js و Git هرگز ریشهای را که شرکت شما در ویندوز یا macOS نصب کرده، یا CA خصوصیای را که سرویسهای داخلی را امضا میکند، نمیبینند. Python که با نصبکننده macOS از python.org نصب شده باشد، به همین دلیل یک مرحله گواهی جداگانه لازم دارد و سیستمها و فایلهای CA قدیمی ممکن است ریشههای عمومی تازهتر را نداشته باشند.
چگونه بفهمید با کدام علت روبهرو هستید؟
به زنجیرهای نگاه کنید که سرور واقعاً میفرستد. Git for Windows همراه خود openssl دارد، پس این فرمان در Git Bash هم اجرا میشود:
openssl s_client -connect localhost:47444 -servername localhost -showcerts </dev/nullسرور ما روی پورت 47444 فقط گواهی برگ را میفرستد. سطرهای مهم:
Certificate chain
0 s:CN=localhost
i:O=Example Corp, CN=Example Corp Issuing CA
Verify return code: 21 (unable to verify the first certificate)s: موضوع (subject) و i: صادرکننده (issuer) است؛ زنجیره کامل یک مدخل 1 s: هم دارد. برای حالت بازرسی، یک پروکسی محلی اجرا کردیم که مانند گیتوی سازمانی ترافیک را با CA به نام Example Corp دوباره امضا میکند و example.com را از طریق آن درخواست کردیم (-proxy 127.0.0.1:47461):
Certificate chain
0 s:CN=example.com
i:O=Example Corp, CN=Example Corp Issuing CA
1 s:O=Example Corp, CN=Example Corp Issuing CA
i:O=Example Corp, CN=Example Corp Root CA
Verify return code: 20 (unable to get local issuer certificate)از طریق یک تونل ساده، همان فرمان زنجیره واقعی سایت را نشان داد که Cloudflare TLS Issuing ECC CA 3 آن را صادر کرده بود، همراه با Verify return code: 0 (ok). خروجی خودتان را اینطور بخوانید:
- فقط مدخل 0، صادرکننده عمومی: سرور گواهی میانی خود را نمیفرستد (علت 1).
- صادرکننده شرکت شما، یک محصول امنیتی یا یک ابزار اشکالزدایی است: چیزی ترافیک را دوباره امضا میکند (علت 2).
- زنجیره عمومی کامل و
0 (ok)، اما ابزار شما شکست میخورد: ابزار مخزن اعتماد دیگری را میخواند (علت 3).
چگونه این خطا را در Python رفع کنیم؟
Requests این خطا را درون سطری طولانیتر میپیچد؛ نوشته خطای Max Retries Exceeded With URL توضیح میدهد بخش Caused by آن را چگونه بخوانید. آزمون ما این خروجی را داد:
requests.exceptions.SSLError: HTTPSConnectionPool(host='localhost', port=47443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1032)')))اگر تیم IT ریشه شرکت را در سیستمعامل نصب کرده است، بگذارید Python از همان مخزن استفاده کند. بسته truststore (Python 3.10 یا بالاتر) کاری میکند که Requests و ماژول ssl از طریق مخزن سیستم تأیید کنند؛ مستندات آن استفاده از inject_into_ssl() را به برنامهها و اسکریپتها محدود میکند، نه کتابخانهها:
import truststore
truststore.inject_into_ssl() # call once, at the start of your script
import requests
print(requests.get("https://example.com/", timeout=10).status_code)در غیر این صورت، فایل CA تازهای با ریشههای certifi بهاضافه ریشه شرکت بسازید و REQUESTS_CA_BUNDLE را به آن اشاره دهید:
cat "$(python -m certifi)" corp-root.pem > ca-bundle-plus-corp.pem
export REQUESTS_CA_BUNDLE="$PWD/ca-bundle-plus-corp.pem"پس از آن هم example.com و هم سرور آزمایشی ما 200 برگرداندند. هرگز ریشه شرکت را بهتنهایی به کار نبرید: این متغیر جای certifi را میگیرد و در آزمون ما example.com در آن حالت با همان خطا شکست خورد. پس از هر بهروزرسانی certifi فایل را دوباره بسازید.
برخلاف Requests، pip از نسخه 24.2 از گواهیهای سیستم هم استفاده میکند (مستندات pip)، پس pip install ممکن است جایی کار کند که Requests شکست میخورد. برای یک فایل CA مشخص، --cert را بدهید یا PIP_CERT را تنظیم کنید. در macOS با نصبکننده python.org، فایل Install Certificates.command را یک بار اجرا کنید.
اگر سایتی که از آن داده جمع میکنید گواهی میانیاش را نمیفرستد، آن را از CA صادرکننده دانلود کنید و به فایل ترکیبی بیفزایید (همین کار سرور فقطبرگ ما را از آزمون گذراند) و به صاحب سایت خبر بدهید.
چگونه این خطا را در Node.js و npm رفع کنیم؟
خروجی npm همان کد Node.js را در خود دارد:
npm error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm error errno UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm error request to https://localhost:47443/demo-pkg failed, reason: unable to get local issuer certificateNode.js ریشههای فایلی را که NODE_EXTRA_CA_CERTS نام میبرد به فهرست داخلی خود اضافه میکند (مستندات Node.js). npm روی Node.js اجرا میشود، پس یک متغیر هر دو را درست میکند:
export NODE_EXTRA_CA_CERTS="$PWD/corp-root.pem"
npm view demo-pkg version --registry https://localhost:47443/فرمان دوم 1.0.0 را چاپ کرد (در PowerShell: $env:NODE_EXTRA_CA_CERTS = "C:\certs\corp-root.pem"). Node.js این متغیر را فقط هنگام راهاندازی میخواند، نه از درون اسکریپتی که در حال اجراست.
اما تنظیم cafile خود npm فهرست مورد اعتماد را جایگزین میکند. وقتی فقط ریشه شرکت در آن بود، درخواست ما به رجیستری عمومی شکست خورد:
npm error request to https://registry.npmjs.org/left-pad failed, reason: unable to get local issuer certificateاگر ریشه از قبل در مخزن سیستم است، Node.js میتواند همان مخزن را بخواند: --use-system-ca در Node.js 23.8.0 و NODE_USE_SYSTEM_CA=1 در نسخههای 24.6.0 و 22.19.0 اضافه شد و هر دو در آزمون ما با npm کار کردند (NODE_OPTIONS=--use-system-ca). دستیارهای برنامهنویسی مبتنی بر هوش مصنوعی که بر پایه Node.js ساخته شدهاند همین متغیرها را میخوانند؛ مستندات Claude Code متغیر NODE_EXTRA_CA_CERTS را برای CAهای سازمانی فهرست کرده است.
چگونه این خطا را در Git رفع کنیم؟
Git با بکاند OpenSSL همان عبارتبندی curl را نشان میدهد:
fatal: unable to access 'https://localhost:47443/repo.git/': SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)در ویندوز، بگذارید Git از مخزن ویندوز استفاده کند. نصبکننده Git for Windows دو گزینه "Use the OpenSSL library" (استفاده از کتابخانه OpenSSL) و "Use the native Windows Secure Channel library" (استفاده از کتابخانه بومی Secure Channel ویندوز) را پیشنهاد میکند؛ بعداً هم میتوانید آن را تغییر دهید:
git config --global http.sslBackend schannelاگر ریشه آنجا هم نباشد، Schannel خطای SEC_E_UNTRUSTED_ROOT (0x80090325) را گزارش میکند. متن این پیام به زبان سیستم است و در ویندوز انگلیسی "The certificate chain was issued by an authority that is not trusted" نوشته میشود، یعنی زنجیره گواهی را مرجعی صادر کرده که مورد اعتماد نیست. Schannel تنظیم http.sslCAInfo را نادیده میگیرد، مگر آنکه http.schannelUseSSLCAInfo تنظیم شده باشد.
روی macOS، لینوکس یا بکاند OpenSSL، Git را فقط برای یک سرور به یک فایل ارجاع دهید:
git config --global http.https://git.example.com/.sslCAInfo /path/to/corp-root.pemدر آزمون ما، میزبان پیکربندیشده از TLS گذشت، میزبان دیگر همچنان شکست خورد و github.com همچنان کار میکرد. اگر گیتوی همه سایتها را بازرسی میکند، از Schannel یا یک فایل ترکیبی (فایل CA خود Git بهاضافه ریشه شرکت) استفاده کنید.
چگونه این خطا را در curl رفع کنیم؟
شماره این خطا در curl عدد 60 است. curl 8.21.0 ما آن را اینطور بیان میکند؛ بیلدهای دیگر SSL certificate problem: unable to get local issuer certificate را چاپ میکنند:
curl: (60) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
More details here: https://curl.se/docs/sslcerts.html--cacert corp-root.pemتأیید را با همان فایل انجام میدهد و جای فایل CA پیشفرض را میگیرد، پس برای سایتهای عمومی هم از یک فایل ترکیبی استفاده کنید.--ca-native(curl 8.2.0 به بعد) مخزن سیستم را به بیلدهای OpenSSL در ویندوز اضافه میکند، و در macOS هم وقتی curl با SecTrust اپل ساخته شده باشد.curl.exeداخلی ویندوز از Schannel و مخزن ویندوز استفاده میکند. با CA خصوصیای که هیچ داده ابطالی منتشر نمیکند، درschannel: the revocation status is unknownمتوقف میشود؛--ssl-revoke-best-effortاین وضعیت را میپذیرد و همچنان زنجیره را بررسی میکند.--proxy-cacertیک پروکسی HTTPS را تأیید میکند، یعنی پروکسیای که با آدرسhttps://به آن وصل میشوید. پروکسی سادهhttp://گواهی خودش را ندارد؛ نوشته استفاده از cURL با پروکسی هر دو حالت را پوشش میدهد.
صفحه پروژه curl درباره تأیید گواهی SSL اکیداً توصیه میکند در محیط عملیاتی هرگز تأیید را کنار نگذارید.
چرا verify=False، -k و NODE_TLS_REJECT_UNAUTHORIZED=0 راهحل نیستند؟
اینها بهجای ترمیم زنجیره، بررسی آن را متوقف میکنند، پس کلاینت هر گواهیای را برای هر نامی میپذیرد، حتی گواهی کسی که روی همان شبکه است و میخواهد ترافیک شما را بخواند؛ مستندات Node.js با صراحت NODE_TLS_REJECT_UNAUTHORIZED=0 را ناامن مینامد. در آزمون Git ما، http.sslVerify=false بدون هیچ هشداری به سرور رسید، پس پیکربندی خراب همانطور باقی میماند. چنین کلیدهایی گسترش هم پیدا میکنند: متغیری در پروفایل شل به همه برنامههای Node.js میرسد و verify=False یک آزمون سر از محیط عملیاتی درمیآورد.
چگونه از سرور خودتان زنجیره کامل بفرستید؟
گواهی برگ و پس از آن همه گواهیهای میانی را پیکربندی کنید و ریشه را کنار بگذارید. در nginx، فایل ssl_certificate نخست گواهی سرور و پس از آن گواهیهای میانی را در خود دارد (مستندات nginx)؛ اگر ترتیب اشتباه باشد، nginx با key values mismatch راهاندازی نمیشود. Certbot برای همین کار fullchain.pem را مینویسد، در حالی که cert.pem فقط گواهی برگ را دارد؛ Apache 2.4.8 و بالاتر fullchain.pem را در SSLCertificateFile میپذیرد. از بیرون با openssl s_client -connect yourdomain:443 -servername yourdomain -showcerts بررسی کنید: باید مدخلهای 0 و 1 و Verify return code: 0 (ok) را ببینید.
دو تغییر در 2026 خودکار کردن این بررسی را ارزشمند میکند. از 15 مارس 2026، الزامات پایه (Baseline Requirements) CA/Browser Forum اعتبار گواهیهای عمومی را به 200 روز محدود کرده است (100 روز از مارس 2027 و 47 روز از مارس 2029)، پس تمدیدها بیشتر میشوند و هر تمدید فرصتی است برای نصب فایل نادرست. در 27 مه 2026، Let's Encrypt پروفایل پیشفرض خود را به گواهیهای میانی Generation Y منتقل کرد که از طریق امضای متقابل (cross-sign) به ریشههای آشنای ISRG میرسند؛ Certify The Web، یک کلاینت گواهی برای ویندوز، مستند کرده است که سرورهای ویندوزی زنجیره کوتاهتر به ریشههای جدید را میفرستند، زنجیرهای که کلاینتهای قدیمیتر نمیتوانند تأییدش کنند.
آیا پروکسی باعث این خطا میشود؟
فقط پروکسیای که ترافیک را رمزگشایی میکند. برای درخواست https:// از طریق پروکسی HTTP، کلاینت CONNECT host:443 را میفرستد و پروکسی بایتهای رمزگذاریشده را جابهجا میکند، پس شما گواهی خود سایت را تأیید میکنید، همانطور که تونل ساده ما نشان داد. گیتویهای Proxynet هم تونل سادهاند: اتصال پروکسی HTTPS به هیچ گواهی ریشهای روی دستگاه شما نیاز ندارد.
وقتی از طریق استخر پروکسی مسکونی داده جمعآوری میکنید، آدرس خروجی تغییر میکند اما گواهی سایت نه، پس خطای زنجیره روی یک هدف در همه آدرسهای خروجی همراه شما میماند؛ چرخاندن IP آن را برطرف نمیکند.
کجا با این خطا روبهرو میشوید
- نصب بسته روی لپتاپ شرکت: npm، pip و yarn پشت گیتویای که TLS را بازرسی میکند شکست میخورند، در حالی که مرورگر کار میکند.
- رانرهای CI و بیلدهای Docker: کانتینر مخزن اعتماد خودش را دارد، پس ریشه شرکت باید داخل ایمیج قرار بگیرد.
- دستیارهای برنامهنویسی مبتنی بر هوش مصنوعی: ابزارهای خط فرمانی که بر پایه Node.js ساخته شدهاند، API خود را از طریق همان گیتوی فرا میخوانند.
- کلاینتهای API: در Postman، Settings (تنظیمات) و سپس Certificates (گواهیها) را باز کنید، CA certificates (گواهیهای CA) را روشن کنید و فایل PEM را انتخاب کنید.
- اسکرپرها: سایتی که گواهی میانیاش گم شده، در همه اسکریپتها شکست میخورد در حالی که در مرورگر باز میشود.
- سرویسهای داخلی: داشبوردها و سرورهای Git که CA شرکت آنها را امضا کرده است.
اشتباهات رایج
- ارجاع
REQUESTS_CA_BUNDLE،cafileدر npm یا--cacertفقط به ریشه شرکت. هر سه فهرست پیشفرض را جایگزین میکنند. - افزودن گواهی نادرست. فایل باید ریشهای را داشته باشد که تیم IT منتشر میکند، نه گواهی برگ یک سایت.
- ذخیره گواهی در قالب دودویی DER. این تنظیمات PEM میخواهند، یعنی قالب متنی که با
-----BEGIN CERTIFICATE-----شروع میشود. - تنظیم
NODE_EXTRA_CA_CERTSدرون اسکریپت. Node.js آن را فقط هنگام راهاندازی میخواند. - نصب
cert.pemبهجایfullchain.pem. مرورگرها ممکن است همچنان کار کنند، پس کسی متوجه نمیشود.
راهنمای انتخاب
| آنچه میبینید | چه باید کرد |
|---|---|
فقط مدخل 0، صادرکننده عمومی | صاحب سایت زنجیره کامل را بفرستد؛ تا آن زمان گواهی میانی را به فایل CA خود بیفزایید |
| صادرکننده شرکت شما، آنتیویروس یا ابزار اشکالزدایی است | آن ریشه را از تیم IT بگیرید و برای هر ابزار جداگانه اضافه کنید |
زنجیره عمومی و 0 (ok)، اما یک ابزار شکست میخورد | بگذارید ابزار مخزن سیستم را بخواند: truststore، --use-system-ca، Schannel |
| npm شکست میخورد | NODE_EXTRA_CA_CERTS؛ cafile فقط با فایل CA کامل |
| Git برای یک سرور داخلی شکست میخورد | http.<url>.sslCAInfo برای همان میزبان |
| curl شکست میخورد | --cacert با فایل ترکیبی، یا --ca-native |
پرسشهای متداول
چرا سایت در مرورگر من باز میشود اما در Python، curl یا Node.js شکست میخورد؟
مرورگر و ابزار مخزنهای اعتماد متفاوتی را میخوانند و مرورگرها زنجیرههای ناقص را خودشان ترمیم میکنند. اسکریپت فایل CA خودش را میخواند و هیچکدام از این دو کار را نمیکند؛ زنجیره را با openssl s_client مقایسه کنید تا ببینید کدام حالت صدق میکند.
آیا استفاده از verify=False، -k یا NODE_TLS_REJECT_UNAUTHORIZED=0 امن است؟
نه بهعنوان راهحل. اینها همه بررسیهای گواهی را خاموش میکنند، پس هر کسی میان شما و سرور میتواند ترافیک را بخواند یا تغییر دهد. حداکثر برای یک فرمان روی سرور آزمایشی خودتان از آنها استفاده کنید.
تفاوت «unable to get local issuer certificate» با «self-signed certificate in certificate chain» چیست؟
هر دو یعنی زنجیره به ریشهای ختم میشود که ابزار شما به آن اعتماد ندارد. در اولی، ریشه فرستاده نشده و بهصورت محلی هم پیدا نشده است؛ در دومی، سرور یا یک پروکسی خود ریشه را فرستاده است. راه رفع یکی است.
گواهی ریشه شرکتم را از کجا بگیرم؟
از تیم IT یا امنیت؛ روی لپتاپ مدیریتشده این گواهی از قبل در مخزن سیستم هست، پس truststore، --use-system-ca و Schannel بدون فایل کار میکنند. هرگز ریشهای را از منبع غیررسمی نگیرید: یک ریشه مورد اعتماد میتواند برای هر دامنهای گواهی امضا کند.
چرا pip روی همان دستگاه کار میکند اما Requests شکست میخورد؟
pip از نسخه 24.2 علاوه بر certifi گواهیهای سیستم را هم بررسی میکند، در حالی که Requests فقط certifi را میخواند. بسته truststore همین رفتار را به اسکریپت شما میدهد.
آیا پروکسی میتواند باعث خطای «unable to get local issuer certificate» شود؟
فقط پروکسیای که ترافیک را رمزگشایی میکند: گیتوی سازمانی، آنتیویروس با اسکن HTTPS یا پروکسی اشکالزدایی. پروکسی تونلی که از CONNECT استفاده میکند، گواهی خود سایت را بدون تغییر عبور میدهد.
خلاصه
این خطا یعنی کلاینت شما نتوانست گواهی سرور را به ریشهای که به آن اعتماد دارد وصل کند. openssl s_client علت را نشان میدهد: گواهی برگ تنها به سرور اشاره دارد، صادرکننده سازمانی به بازرسی TLS و زنجیره عمومی سالم به فایل CA خود ابزار. ریشه درست را همان جایی بگذارید که ابزار به آن نگاه میکند و تأیید را روشن نگه دارید. برای پروکسیهایی که ترافیک را بدون دست زدن به گواهیها تونل میکنند، خدمات پروکسی ما را ببینید.




