A Logstash http input gives applications, CI jobs, and webhook senders a simple ingestion endpoint, which is useful when events need to enter a pipeline without deploying Beats or standing up a message broker first.
The http input listens on a host and port, accepts HTTP requests, and turns each request body into a Logstash event. Current plugin builds already map application/json requests through the default additional_codecs setting, and assigning an explicit input id makes the pipeline stats API show which listener is receiving events.
If host is omitted, current releases bind the listener to 0.0.0.0 by default. Keep the first validation run on 127.0.0.1 when possible, because remote exposure should be paired with ssl_enabled plus either user and password or ssl_client_authentication, and Logstash 9.x also rejects legacy TLS keys such as ssl and ssl_verify_mode that still appear in older examples.
input {
http {
id => "http_webhook_8080"
host => "127.0.0.1"
port => 8080
}
}
output {
stdout {
codec => rubydebug
}
}
Current HTTP input releases already decode application/json request bodies through the default additional_codecs mapping, so an explicit codec ⇒ json is usually unnecessary unless clients send a different content type or need a custom mapping. The temporary stdout output keeps the first validation focused on the input itself before a production output is added.
Omitting host binds the listener to 0.0.0.0 by default. If remote systems must connect, replace the localhost bind with the required service address and add ssl_enabled plus user and password or ssl_client_authentication. Current Logstash 9.x builds also fail to start when old TLS keys such as ssl, ssl_verify_mode, or verify_mode are still present.
$ sudo -u logstash /usr/share/logstash/bin/logstash --path.settings /etc/logstash --path.data /tmp/logstash-http-input-configtest --config.test_and_exit -f /etc/logstash/conf.d/20-http-input.conf
Using bundled JDK: /usr/share/logstash/jdk
[2026-04-07T08:51:30,826][INFO ][logstash.runner ] Starting Logstash {"logstash.version"=>"9.3.2", "jruby.version"=>"jruby 9.4.13.0 (3.1.4) 2025-06-10 9938a3461f OpenJDK 64-Bit Server VM 21.0.10+7-LTS on 21.0.10+7-LTS +indy +jit [aarch64-linux]"}
[2026-04-07T08:51:31,205][WARN ][logstash.config.source.multilocal] Ignoring the 'pipelines.yml' file because command line options are specified
[2026-04-07T08:51:32,041][INFO ][logstash.javapipeline ][main] Pipeline `main` is configured with `pipeline.ecs_compatibility: v8` setting. All plugins in this pipeline will default to `ecs_compatibility => v8` unless explicitly configured otherwise.
Configuration OK
[2026-04-07T08:51:32,042][INFO ][logstash.runner ] Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash
The temporary --path.data directory must be writable by the logstash user. Using -f isolates this file for validation, so Logstash warns that /etc/logstash/pipelines.yml is ignored for that run.
Current Logstash 9.x releases do not allow superuser runs by default. Running the same command as root fails unless allow_superuser is explicitly set to true in /etc/logstash/logstash.yml.
$ sudo systemctl restart logstash
Restarting Logstash briefly pauses active pipelines, so senders may buffer, back off, or see temporary failures until the listener is back.
$ sudo systemctl status logstash --no-pager --lines=20
● logstash.service - logstash
Loaded: loaded (/usr/lib/systemd/system/logstash.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-04-07 08:53:45 UTC; 11s ago
Main PID: 22164 (java)
Tasks: 95 (limit: 28486)
Memory: 962.4M
CPU: 15.104s
##### snipped #####
Apr 07 08:53:45 logstash-01 systemd[1]: Started logstash.service - logstash.
If the unit does not stay active (running), inspect /var/log/logstash/logstash-plain.log or the journal before retrying the restart.
$ sudo ss -lntp | grep -F ':8080'
LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* users:(("java",pid=22164,fd=196))
If host is changed to a service address or 0.0.0.0, ss should show that bind target instead of 127.0.0.1.
$ curl -si http://127.0.0.1:8080 -H 'Content-Type: application/json' -d '{"message":"webhook validation","service":"webhook"}'
HTTP/1.1 200 OK
content-length: 2
content-type: text/plain
ok
Current HTTP input releases apply the json codec automatically for application/json requests. If clients send another content type, the default plain codec is used unless additional_codecs or codec is configured explicitly.
If the client receives 429 or times out, the pipeline is backlogged. Elastic's current plugin reference recommends retrying with exponential backoff and jitter instead of sending the same request in a tight loop.
$ curl -s http://localhost:9600/_node/stats/pipelines/main?pretty
{
"pipelines" : {
"main" : {
"events" : {
"out" : 1,
"queue_push_duration_in_millis" : 0,
"filtered" : 1,
"in" : 1,
"duration_in_millis" : 62
},
"plugins" : {
"inputs" : [ {
"id" : "http_webhook_8080",
"name" : "http",
"events" : {
"out" : 1,
"queue_push_duration_in_millis" : 0
}
} ]
}
}
}
}
The input id makes the stats API easy to read when a pipeline has multiple listeners. On current package installs, the Logstash HTTP API uses the api.enabled, api.http.host, and api.http.port settings in /etc/logstash/logstash.yml; older http.* API setting names were removed in Logstash 9.x.
$ sudo journalctl --unit=logstash --since "5 minutes ago" --no-pager --lines=40
Apr 07 08:53:45 logstash-01 logstash[22164]: [2026-04-07T08:53:45,171][INFO ][logstash.javapipeline ][main] Pipeline started {"pipeline.id"=>"main"}
Apr 07 08:53:45 logstash-01 logstash[22164]: [2026-04-07T08:53:45,191][INFO ][logstash.agent ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
Apr 07 08:53:56 logstash-01 logstash[22164]: "message" => "webhook validation"
With the temporary stdout output shown earlier, the journal includes the emitted event. After replacing stdout with a production output, confirm success at that destination instead of expecting full events in the journal.
When webhook JSON keys overlap ECS fields such as host, http, or url, current Logstash releases log a warning and decode those keys at the event root. Use an explicit JSON codec target if those payload names must be kept separate.