apache/shenyu · error · ShenyuException

The sslCrtAndKeys can not be null

Error message

The sslCrtAndKeys can not be null

What it means

ShenyuSniAsyncMapping's parameterized constructor builds SNI SSL providers from a list of certificate/key files; a null or empty list means no SNI mapping could be created, so it throws ShenyuException('The sslCrtAndKeys can not be null'). The gateway needs at least one cert/key pair to construct Http11SslContextSpec entries for domain-based TLS routing.

Solutions

  1. Configure at least one ssl cert/key pair (keyCertChainFile + keyFile) under the shenyu SNI settings before constructing the mapping.
  2. Verify the file paths exist and are readable — next failure after an empty list is typically file-not-found.
  3. Check the code path building the list (config parsing/filtering) for why it returned empty.
  4. If SNI is not needed, avoid constructing ShenyuSniAsyncMapping with the empty list rather than passing it defensively.

Example fix

// before
List<SslCrtAndKeyFile> certs = sniConfig.getCerts(); // may be empty
new ShenyuSniAsyncMapping(certs);
// after
if (certs != null && !certs.isEmpty()) {
    new ShenyuSniAsyncMapping(certs);
} else {
    LOG.warn("SNI disabled: no certificates configured");
}
Defensive patterns

Strategy: validation

Validate before calling

if (sslCrtAndKeys == null || sslCrtAndKeys.isEmpty()) {
    throw new IllegalArgumentException("at least one SNI cert/key pair is required");
}

Type guard

boolean hasCerts(List<SslCrtAndKeyFile> l) {
    return l != null && !l.isEmpty();
}

Try / catch

try {
    new ShenyuSniAsyncMapping(certs);
} catch (ShenyuException e) {
    LOG.error("SNI init failed: {}", e.getMessage());
}

Prevention

When it happens

Trigger: new ShenyuSniAsyncMapping(list) where list is null or isEmpty() — e.g. shenyu.sni.* configuration resolved to zero certificate entries.

Common situations: SNI enabled in bootstrap config but no crt/key file paths configured; a config loader returning an empty list when file globs match nothing; property names mistyped so cert entries aren't parsed.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/b552bbd926bdf3b4. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-common/src/main/java/org/apache/shenyu/common/config/ssl/ShenyuSniAsyncMapping.java:48

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

/**
 * Sni async map, can be used to dynamically configure ssl certificates.
 */
public class ShenyuSniAsyncMapping implements AsyncMapping<String, SslProvider> {

    private final ConcurrentHashMap<String, SslProvider> sslProviderMap;

    public ShenyuSniAsyncMapping() {
        this.sslProviderMap = new ConcurrentHashMap<>();
    }

    public ShenyuSniAsyncMapping(final List<SslCrtAndKeyFile> sslCrtAndKeys) {
        if (Objects.isNull(sslCrtAndKeys) || sslCrtAndKeys.isEmpty()) {
            throw new ShenyuException("The sslCrtAndKeys can not be null");
        }
        this.sslProviderMap = new ConcurrentHashMap<>();
        sslCrtAndKeys.forEach(sslCrtAndKey -> {
            Http11SslContextSpec sslContextSpec = Http11SslContextSpec.forServer(new File(sslCrtAndKey.getKeyCertChainFile()),
                    new File(sslCrtAndKey.getKeyFile()));
            SslProvider sslProvider = SslProvider.builder().sslContext(sslContextSpec).build();
            this.sslProviderMap.put(sslCrtAndKey.getDomain(), sslProvider);
        });
    }

    /**
     * Add SslProvider by domain.
     *
     * @param domain domain
     * @param sslProvider SslProvider
     */
    public void addSslProvider(final String domain, final SslProvider sslProvider) {
        sslProviderMap.put(domain, sslProvider);

View on GitHub (pinned to 567142e072)