There can be a go-between between the root and the site — an intermediate CA.
A CA guards its root key and rarely signs anything with it — mostly the certificates of intermediate CAs. The intermediate CA is signed by the root, and it is the intermediate that signs site certificates. The result is a chain: app.lab.test ← Lab Issuing CA ← Lab Root CA.
The client walks it link by link: the issuer of the site certificate is Lab Issuing CA, the issuer of Lab Issuing CA is Lab Root CA, and Lab Root CA is in the store. The store holds roots only. The client gets intermediate certificates from the server, at the same start of TLS as the site certificate.
openssl s_client from the previous lesson also prints the chain the server sent: the s: line is a certificate's subject, i: is its issuer, and number 0 is the site certificate. grep -A1 ' s:' keeps just these pairs of lines from the output.
See what the server sent
See which certificates app.lab.test sends at the start of TLS.
nginx sent one certificate — the one in the ssl_certificate file. curl has no Lab Issuing CA certificate, neither in the store nor in the server's reply. It has nothing to verify the site's signature with — hence unable to get local issuer certificate.
A browser on your laptop sometimes opens such a site: it keeps intermediate certificates from other sites or downloads the missing one itself. curl, scripts and other servers cannot do that, so after an edit you check the chain with curl.