Skip to content

@SECLEVEL=X does not enable TLSv1 #60569

Description

@davidebombelli

Affected URL(s)

https://nodejs.org/api/tls.html#setting-security-levels

Description of the problem

After running the below script:

import { createServer, connect } from 'node:tls';
const port = 443;

createServer({ ciphers: 'DEFAULT@SECLEVEL=0', minVersion: 'TLSv1' }, function(socket) {
  console.log('Client connected with protocol:', socket.getProtocol());
  socket.end();
  this.close();
})
.listen(port, () => {
  connect(port, { ciphers: 'DEFAULT@SECLEVEL=0', maxVersion: 'TLSv1' });
});

I get the error:

node:events:486
      throw er; // Unhandled 'error' event
      ^

Error: 80F3C7A933760000:error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available:../deps/openssl/openssl/ssl/statem/statem_lib.c:155:

    at TLSSocket._start (node:internal/tls/wrap:1097:16)
    at Object.onceWrapper (node:events:622:28)
    at TLSSocket.emit (node:events:520:35)
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1622:10)
Emitted 'error' event on TLSSocket instance at:
    at emitErrorNT (node:internal/streams/destroy:170:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
  library: 'SSL routines',
  reason: 'no protocols available',
  code: 'ERR_SSL_NO_PROTOCOLS_AVAILABLE'
}

It seems like tls.DEFAULT_MIN_VERSION is TLSv1.2. Maybe when setting a lower maxVersion, this property is not automatically lowered.

Activity

  1. added
    docIssues and PRs related to Node.js documentation.
    on Nov 3, 2025
  2. Sarang-Patel commented on Nov 3, 2025

    @Sarang-Patel

    I was able to get the same error for v1. Yes, it does seem that with a lower maxVersion, there are no protocols to support since it doesn't automatically switch to lower one. Also, another thing to add, even if the maxVersion is set to v1.2, a 'sslv3 alert handshake failure', can still occur due to weaker ciphers or low security levels.

    I will update the docs to add a note for this after the section.

  3. Sarang-Patel commented on Nov 3, 2025

    @Sarang-Patel

    Hello, I have added a commit updating the doc.

    This is my first contribution, so please let me know if anything isn't done as expected and I would be happy to update.

  4. github-actions commented on Jun 2, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  5. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jun 2, 2026
  6. davidebombelli commented on Jun 2, 2026

    @davidebombelli
    Author

    This issue is not stale, as in v26.3.0 it throws the same error and the docs were never changed.

  7. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jun 3, 2026
  8. pimterry commented on Jun 3, 2026

    @pimterry
    Member

    @davidebombelli Can you explain why lowering the seclevel should reduce the default TLS level? AFAICT the docs don't suggest anywhere that it does that, and there's plenty of reasons you might not expect this (e.g. lowering the seclevel to enable other now-deprecated OpenSSL features, but with TLS 1.2). We generally don't want to enable insecure configurations except in the most explicit circumstances when you very very clearly configure that.

    Is there somewhere in our docs or the referenced OpenSSL docs that does say we do this, or imply something similar?

    The max vs min issue discussed here and addressed in the PR is independent of the seclevel question, you can hit the same problem without changing the seclevel. I'm not opposed to documenting this, but honestly it's a bit of a footgun and we should probably just fix it instead of documenting the bad behaviour. I'd be open to a PR that made this fail explicitly with a clear validation error instead (failing immediately & clearly, instead of delaying the failure to handshake time, and throwing a confusing raw OpenSSL error when we get there). That would be semver-major since it could break some (very weird) code, so we'd have to defer releasing it until Node v27, but that's OK and it'd be a good improvement. PRs welcome.

  9. davidebombelli commented on Jun 3, 2026

    @davidebombelli
    Author

    Hello @pimterry, I did not come up with the code on my own, it is written in the documentation at the link I provided. And it is broken code.
    I am not suggesting to changing the implementation of the API, but instead to change documentation.

  10. pimterry commented on Jun 3, 2026

    @pimterry
    Member

    Ah, gotcha, I didn't realise that code was from there directly! That's much clearer thanks.

    That just seems like a bug in the example. That code really should fail, so I think the behaviour itself is correct (although the error could be improved), but we should fix the docs to so this works as expected.

    Want to open a quick docs PR? I think we just need to add minVersion: 'TLSv1' to the connect() call so it sets both min & max there.

  11. soreavis commented on Aug 18, 2026

    @soreavis
    Contributor

    @pimterry the minVersion: 'TLSv1' addition alone doesn't quite get there — it clears the no protocols available error, and then the handshake dies at alert 40, because the example's createServer is given no key or cert, so the server has no shared cipher. PR with both is up: #65391 — the server-key.pem/server-cert.pem placeholders from the other tls.md examples, plus ca on the client and the same openssl req recipe those sections carry, so it runs from an empty directory. I also moved the port to the 8000 the rest of the file uses. Can trim any of it back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docIssues and PRs related to Node.js documentation.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions