{"record":{"id":"f560419af422d235","repo":"puma/puma","slug":"no-such-truststore-file-truststore","errorCode":null,"errorMessage":"No such truststore file '#{truststore}'","messagePattern":"No such truststore file '#(.+?)'","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puma/minissl.rb","lineNumber":248,"sourceCode":"        attr_reader :keystore\n        attr_reader :keystore_type\n        attr_accessor :keystore_pass\n        attr_reader :truststore\n        attr_reader :truststore_type\n        attr_accessor :truststore_pass\n        attr_reader :cipher_suites\n        attr_reader :protocols\n\n        def keystore=(keystore)\n          check_file keystore, 'Keystore'\n          @keystore = keystore\n        end\n\n        def truststore=(truststore)\n          # NOTE: historically truststore was assumed the same as keystore, this is kept for backwards\n          # compatibility, to rely on JVM's trust defaults we allow setting `truststore = :default`\n          unless truststore.eql?(:default)\n            raise ArgumentError, \"No such truststore file '#{truststore}'\" unless File.exist?(truststore)\n          end\n          @truststore = truststore\n        end\n\n        def keystore_type=(type)\n          raise ArgumentError, \"Invalid keystore type: #{type.inspect}\" unless ['pkcs12', 'jks', nil].include?(type)\n          @keystore_type = type\n        end\n\n        def truststore_type=(type)\n          raise ArgumentError, \"Invalid truststore type: #{type.inspect}\" unless ['pkcs12', 'jks', nil].include?(type)\n          @truststore_type = type\n        end\n\n        def cipher_suites=(list)\n          list = list.split(',').map(&:strip) if list.is_a?(String)\n          @cipher_suites = list\n        end","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/puma/puma/blob/b8341dc946f0a2444e5ea6730d1967ca53c8d006/lib/puma/minissl.rb#L230-L266","documentation":"JRuby-only: MiniSSL::Context#truststore= (lib/puma/minissl.rb:248) validates the truststore path unless the value is exactly the symbol :default (which opts out and uses the JVM's default trust anchors). Any other value must point to an existing file or ArgumentError is raised.","triggerScenarios":"`ssl_bind` with a truststore option whose path does not exist on disk. Note the standard ContextBuilder converts the string 'default' to :default (lib/puma/minissl/context_builder.rb:27), so :default handling only applies through ssl_bind - assigning ctx.truststore = 'default' (String) directly checks for a literal file named 'default'.","commonSituations":"Porting an MRI puma config to JRuby where the truststore was never provisioned; wrong path after switching from system JAVA_HOME cacerts to a custom truststore; typos in the path.","solutions":["Create/copy the truststore (e.g. keytool -importcert) and point to its absolute path","To rely on JVM defaults, pass `ssl_truststore: 'default'` through ssl_bind","If configuring Context directly in Java/JRuby code, use the symbol :default, not the string"],"exampleFix":"# before\nssl_bind '0.0.0.0', '9292', {\n  keystore: 'keystore.jks',\n  'truststore' => '/etc/puma/truststore.jks'  # file not present\n}\n\n# after - use JVM default trust anchors\nssl_bind '0.0.0.0', '9292', {\n  keystore: 'keystore.jks',\n  'truststore' => 'default'\n}","handlingStrategy":"validation","validationCode":"ts = ENV['SSL_TRUSTSTORE']\nssl_bind host, port, {\n  keystore: keystore,\n  truststore: (ts == 'default' || File.exist?(ts) ? ts : abort(\"missing truststore #{ts}\"))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember `truststore 'default'` means JVM trust anchors; only via ssl_bind is the string converted to the symbol","Provision truststores with keytool before deploy, alongside the keystore","Use absolute paths for JVM-related files"],"tags":["puma","jruby","ssl","tls","truststore","keystore","configuration"],"backgroundTag":"ssl-truststore-not-found","analyzedSha":"b8341dc946f0a2444e5ea6730d1967ca53c8d006","analyzedAt":"2026-08-21T18:40:40.221Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}