{"id":13566,"date":"2026-10-15T07:50:00","date_gmt":"2026-10-15T05:50:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=13566"},"modified":"2026-10-09T23:06:13","modified_gmt":"2026-10-09T21:06:13","slug":"certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/","title":{"rendered":"Certificate Chains: Why a Site Opens in the Browser and Fails in curl"},"content":{"rendered":"<p>A TLS handshake looks like a single yes or no. In fact it is a small proof: the server presents a certificate, and the client has to build a path from that certificate to a root it already trusts. The proof succeeds or it does not, and the answer depends on who is asking.<\/p>\n<p>That is the part which surprises people. The same server, at the same second, can be trusted by Chrome and refused by curl.<\/p>\n<figure class=\"lw-diagram\">\n<img decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/zertifikatskette-en.png\" width=\"1120\" height=\"580\" loading=\"lazy\" alt=\"An incomplete certificate chain judged twice: the browser fetches the missing intermediate and succeeds, curl does not and fails\"><figcaption>One incomplete chain, two verdicts &#8211; the difference is a fetch that only one of the two performs.<\/figcaption><\/figure>\n<h2>What travels in a handshake<\/h2>\n<p>The server sends its own certificate, called the leaf, and normally one or two more above it. The leaf carries the host names it is valid for, a public key and a signature. The signature was not made by the root; it was made by an intermediate certificate, which in turn was signed by the root.<\/p>\n<p>The root itself is never sent. It sits in the trust store of the operating system or the browser, a few hundred of them, and it is the only part the client already has.<\/p>\n<p>So the client needs everything between the leaf and that root. If the server does not send the intermediate, there is a gap, and a gap means no proof.<\/p>\n<h2>The link that goes missing<\/h2>\n<p>Nearly every certificate authority ships two files: the certificate itself, and a bundle that contains the certificate plus the intermediate. With Let&#8217;s Encrypt these are <code>cert.pem<\/code> and <code>fullchain.pem<\/code>. The names are not decorative.<\/p>\n<p>Configuring <code>cert.pem<\/code> where <code>fullchain.pem<\/code> belongs is the single most common TLS misconfiguration, and it is easy to see why: the site opens perfectly afterwards. Nothing warns, nothing logs, and the certificate is genuinely valid.<\/p>\n<p>The gap only exists for clients that refuse to close it themselves.<\/p>\n<h2>Why the browser forgives<\/h2>\n<p>A certificate contains a field called Authority Information Access. Among other things it holds a URL: the place where the issuing intermediate can be downloaded. Browsers use it. When the chain is short by one link, they fetch the missing certificate from that address, complete the path and show the padlock.<\/p>\n<p>Some browsers also cache intermediate certificates seen on other sites. This makes the problem harder to reproduce: a server with an incomplete chain can appear to work correctly on two machines, but for a different reason on each.<\/p>\n<p>curl, OpenSSL, most HTTP libraries in Python, PHP, Go and Java do not do this. They read the same field and ignore it, because following it turns one handshake into two network round trips and adds a dependency on a third-party host in the middle of a connection that is supposed to be direct. The refusal is deliberate.<\/p>\n<p>The result is a failure mode with a very specific shape: the website works, and the machine-to-machine traffic does not. Payment providers calling a webhook, a monitoring probe, a mobile app, a partner pulling an API &#8211; all of them report <code>unable to get local issuer certificate<\/code>, while the browser shows nothing at all.<\/p>\n<figure class=\"lw-illu\">\n<img decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/illustrationen\/illu-zertifikatskette.webp\" width=\"1120\" height=\"580\" loading=\"lazy\" alt=\"Two chains side by side: the upper one unbroken, the lower one with an open gap where a link is missing\"><br \/>\n<\/figure>\n<h2>What twelve sites actually send<\/h2>\n<p>Twelve well-known addresses were measured on 2 September 2026, reading only what the server offered during the handshake.<\/p>\n<p>Six sent three certificates, six sent four. Not one sent the leaf alone. The lifetime was identical across all twelve: 90 days, which is what the automated issuers hand out and what the industry has converged on. The remaining validity ranged from 31 to 88 days, with a median of 70 &#8211; the spread that automatic renewal at the two-thirds mark produces.<\/p>\n<p>Eleven of the twelve negotiated TLS 1.3, one settled on 1.2. None accepted TLS 1.0. Nine used an ECDSA key rather than RSA. Eight certificates came from Let&#8217;s Encrypt, three from Google Trust Services, one from Sectigo.<\/p>\n<p>The number of names in a certificate varied far more than anything else: one name at the low end, 41 at wikipedia.org. That number is not a quality signal, only a hint at how the estate is organised.<\/p>\n<h2>Names, not the common name<\/h2>\n<p>A second failure looks similar from the outside. The certificate is complete and valid, but the host is not listed in it.<\/p>\n<p>Current browsers ignore the common name entirely and match only against the subject alternative names. A certificate for <code>example.com<\/code> that omits <code>www.example.com<\/code> covers exactly one of the two, and the redirect between them fails before it can start.<\/p>\n<p>Wildcards cover one label and no more. <code>*.example.com<\/code> matches <code>www.example.com<\/code>, but neither <code>example.com<\/code> itself nor <code>a.b.example.com<\/code>. Both halves of that sentence cost somebody an outage regularly.<\/p>\n<h2>Reading it without a browser<\/h2>\n<p>The distinction that matters cannot be seen in a browser, precisely because the browser repairs it. It needs a client that does not.<\/p>\n<pre><code>openssl s_client -connect example.com:443 -servername example.com &lt; \/dev\/null\ncurl -vI https:\/\/example.com\/<\/code><\/pre>\n<p>In the OpenSSL output, the certificate chain block lists what the server sent. One entry means the intermediate is missing, regardless of whether the verification line below it says ok &#8211; a locally cached intermediate can make even that misleading. Counting what arrived is the reliable measure.<\/p>\n<p>The same reading, without a shell, is what the <a href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/tls-certificate-handshake-inspector\/\">TLS Certificate and Handshake Inspector<\/a> in the toolbox produces: it opens the handshake, verifies once with the trust store and once without, lists the chain exactly as the server sent it, and then tries each TLS version separately. The gap shows up as a chain of one, next to a verification that failed for a reason worth reading.<\/p>\n<div class=\"lw-faq\">\n<h2>Questions and answers<\/h2>\n<h3>Does the root certificate belong in the chain the server sends?<\/h3>\n<p>No. The client has to trust the root already, so a root sent along proves nothing and only adds bytes to every handshake; RFC 8446 explicitly allows it to be omitted. What matters is that every intermediate between the leaf and the root is included, and that is exactly what fullchain.pem contains.<\/p>\n<h3>The chain worked for months, and now a webhook sender suddenly reports unable to get local issuer certificate. What could be behind it?<\/h3>\n<p>If nothing on the server was changed, two causes are the most likely, one on each side of the connection:<\/p>\n<ol>\n<li>The intermediate has changed. Certificate authorities move to new intermediates from time to time. A configuration that combines cert.pem with an intermediate file placed by hand at some point sends, after the next renewal, a link that no longer matches the leaf, and the path then has the same gap as with no intermediate at all. fullchain.pem is rewritten with the matching intermediate at every renewal and does not have this problem.<\/li>\n<li>The client\u2019s trust store is out of date. If the chain ends at a different root after a renewal, that root may be missing from old operating systems or from container images that have not been rebuilt for a long time. The message is the same, although the server sends everything correctly.<\/li>\n<\/ol>\n<p>Counting again settles which of the two applies: if openssl s_client shows the leaf and the intermediate arriving and a current system verifies the chain, the problem lies in the sender\u2019s trust store, and only an update of its CA list helps.<\/p>\n<\/div>\n<div class=\"lw-quellen\">\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8446.html\" target=\"_blank\" rel=\"noopener noreferrer\">RFC 8446: TLS 1.3<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A server that sends only its own certificate looks fine in every browser and fails in curl, in payment callbacks and in webhooks. The reason is a repair that browsers perform quietly and other clients do not.<\/p>\n","protected":false},"author":1,"featured_media":13596,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[137],"tags":[91144,91219,91115],"class_list":["post-13566","post","type-post","status-publish","format-standard","hentry","category-tutorials-en-it-networks","tag-devops","tag-tutorial","tag-web-security"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Certificate Chains: Why a Site Opens in the Browser and Fails in curl | Lukas Wojcik<\/title>\n<meta name=\"description\" content=\"Why an incomplete TLS chain passes in the browser and breaks curl and webhooks, what twelve well-known sites actually send, and how the missing intermediate is found.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Certificate Chains: Why a Site Opens in the Browser and Fails in curl | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Why an incomplete TLS chain passes in the browser and breaks curl and webhooks, what twelve well-known sites actually send, and how the missing intermediate is found.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-15T05:50:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13566-tls-certificate-chain-incomplete-g.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"Certificate Chains: Why a Site Opens in the Browser and Fails in curl\",\"datePublished\":\"2026-10-15T05:50:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/\"},\"wordCount\":1174,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13566-tls-certificate-chain-incomplete-g.png\",\"keywords\":[\"DevOps\",\"Tutorial\",\"Web Security\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/\",\"name\":\"Certificate Chains: Why a Site Opens in the Browser and Fails in curl | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13566-tls-certificate-chain-incomplete-g.png\",\"datePublished\":\"2026-10-15T05:50:00+00:00\",\"description\":\"Why an incomplete TLS chain passes in the browser and breaks curl and webhooks, what twelve well-known sites actually send, and how the missing intermediate is found.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13566-tls-certificate-chain-incomplete-g.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13566-tls-certificate-chain-incomplete-g.png\",\"width\":1200,\"height\":630,\"caption\":\"Certificate Chains: Why a Site Opens in the Browser and Fails in curl\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/it-networks\\\/tutorials-en-it-networks\\\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Certificate Chains: Why a Site Opens in the Browser and Fails in curl\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Certificate Chains: Why a Site Opens in the Browser and Fails in curl | Lukas Wojcik","description":"Why an incomplete TLS chain passes in the browser and breaks curl and webhooks, what twelve well-known sites actually send, and how the missing intermediate is found.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/","og_locale":"en_US","og_type":"article","og_title":"Certificate Chains: Why a Site Opens in the Browser and Fails in curl | Lukas Wojcik","og_description":"Why an incomplete TLS chain passes in the browser and breaks curl and webhooks, what twelve well-known sites actually send, and how the missing intermediate is found.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-10-15T05:50:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13566-tls-certificate-chain-incomplete-g.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"Certificate Chains: Why a Site Opens in the Browser and Fails in curl","datePublished":"2026-10-15T05:50:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/"},"wordCount":1174,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13566-tls-certificate-chain-incomplete-g.png","keywords":["DevOps","Tutorial","Web Security"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/","name":"Certificate Chains: Why a Site Opens in the Browser and Fails in curl | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13566-tls-certificate-chain-incomplete-g.png","datePublished":"2026-10-15T05:50:00+00:00","description":"Why an incomplete TLS chain passes in the browser and breaks curl and webhooks, what twelve well-known sites actually send, and how the missing intermediate is found.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13566-tls-certificate-chain-incomplete-g.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13566-tls-certificate-chain-incomplete-g.png","width":1200,"height":630,"caption":"Certificate Chains: Why a Site Opens in the Browser and Fails in curl"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/it-networks\/tutorials-en-it-networks\/certificate-chains-why-a-site-opens-in-the-browser-and-fails-in-curl\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Certificate Chains: Why a Site Opens in the Browser and Fails in curl"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=13566"}],"version-history":[{"count":3,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13566\/revisions"}],"predecessor-version":[{"id":22067,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13566\/revisions\/22067"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/13596"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=13566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=13566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=13566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}