{"record":{"id":"d1d53fc1b130d541","repo":"elastic/elasticsearch","slug":"65-d1d53f","errorCode":"65","errorMessage":"installation aborted by user","messagePattern":"installation aborted by user","errorType":"exception","errorClass":"UserException","httpStatus":null,"severity":"warning","filePath":"distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/PluginSecurity.java","lineNumber":77,"sourceCode":"                // print all entitlements:\n                for (String entitlement : requested) {\n                    terminal.errorPrintln(Verbosity.NORMAL, \"* \" + entitlement);\n                }\n                terminal.errorPrintln(Verbosity.NORMAL, \"See \" + ENTITLEMENTS_DESCRIPTION_URL);\n                terminal.errorPrintln(Verbosity.NORMAL, \"for descriptions of what these entitlements allow and the associated risks.\");\n\n                if (batch == false) {\n                    prompt(terminal);\n                }\n            }\n        }\n    }\n\n    private static void prompt(final Terminal terminal) throws UserException {\n        terminal.println(Verbosity.NORMAL, \"\");\n        String text = terminal.readText(\"Continue with installation? [y/N]\");\n        if (text.equalsIgnoreCase(\"y\") == false) {\n            throw new UserException(ExitCodes.DATA_ERROR, \"installation aborted by user\");\n        }\n    }\n}\n","sourceCodeStart":59,"sourceCodeEnd":81,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/PluginSecurity.java#L59-L81","documentation":"Thrown by PluginSecurity.prompt when the user, asked `Continue with installation? [y/N]` after reviewing plugin security permissions, answers anything other than `y` (case-insensitive). It is the user-driven abort path with exit code DATA_ERROR (65). Note PluginsConfig.validate throws a generic RuntimeException for the same family of validation; here the CLI uses UserException so the exit code is meaningful.","triggerScenarios":"A plugin ships a plugin-security.policy with extended permissions; PluginSecurity prints the permissions, prompts in non-batch mode, and on a non-`y` answer throws. Running interactively and pressing Enter (default N), or typing `n`, triggers it.","commonSituations":"Operator reviews the security policy of a third-party plugin and declines; CI scripts that forget `--batch` get an interactive prompt and time out / get an N; piping `/dev/null` as stdin yields empty input which is not `y`.","solutions":["If you accept the permissions, answer `y` at the prompt or pass `--batch` to auto-accept.","If you do not accept, remove the plugin from your install list and find an alternative or build it yourself with a narrower policy.","In automated installs always pass `--batch` to avoid an interactive prompt that defaults to abort."],"exampleFix":"# before (interactive, declined):\n#   Continue with installation? [y/N] n   -> exit 65\n# after (auto-accept in CI):\nbin/elasticsearch-plugin install analysis-icu --batch","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    installAction.execute(...);\n} catch (UserException e) {\n    if (e.exitCode == ExitCodes.DATA_ERROR && e.getMessage().contains(\"aborted\")) {\n        // user declined — treat as non-error in interactive flows\n        return Optional.empty();\n    }\n    throw e;\n}","preventionTips":["Always pass `--batch` in automated/CI installs to avoid interactive prompts.","Provide a non-interactive stdin (or accept the policy) when scripting.","Document that defaulting to N is intentional for safety on unknown policies."],"tags":["plugin-install","user-input","security-policy","plugin-cli"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}