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.

Steps to configure a Logstash HTTP input:

  1. Create a dedicated pipeline file such as /etc/logstash/conf.d/20-http-input.conf.
    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.

  2. Test the pipeline configuration with the packaged settings directory and a temporary data path.
    $ 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.

  3. Restart the Logstash service so it loads the new input.
    $ 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.

  4. Confirm the Logstash service returned to an active (running) state.
    $ 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.

  5. Verify the http listener is bound to TCP port 8080.
    $ 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.

  6. Send a test JSON event to the HTTP input endpoint.
    $ 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.

  7. Query the Logstash pipeline stats API and confirm the configured input id handled the event.
    $ 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.

  8. Review recent Logstash journal lines for pipeline startup and the decoded event.
    $ 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.