[Solved] Fixing 415 Unsupported Media Error

Added by Jay 3 months ago

Hello dear Lighttpd community,

I am having a problem that is probably super easy to fix, but even after hours of googling and trying different things, I don't get it, so I hope it's ok to ask my question here.

My situation: I have lighttpd running on a linux device. I want commands to be sent to a fastcgi server. This works well so far. However, ultimately I want to be able to parse SOAP messages with my fastcgi server. (to be precise, I want to implement the ONVIF standard)

The problem is or seems to be that such messages will have "Content-Type: application/soap+xml; charset=utf-8" in their header. When I send such a message to my device, I am given a "415 Unsupported Media Type" Error.

I thought that this can be fixed by adding to mimetype.assign (I post my config below) in the config file, but this didn't solve my problem. Anyway I feel like this kind of problem should be easily solvable, I would expect that I just need to add somewhere that lighttpd should accept application/soap+xml stuff. It doesn't even need to do something with it, just forward it to my fastcgi server. Alas, I failed to figure out what I have to add where.

Of course it's perfectly possible that my particular way of testing things is just flawed. I am using curl to send the following command:

curl -X POST -H "Content-Type: application/soap+xml; charset=utf-8" -d '<s:Envelope xmlns:s=""><s:Body xmlns:xsi="" xmlns:xsd=""><GetNetworkProtocols></GetNetworkProtocols></s:Body></s:Envelope>'

(note that just using /onvif/ in the URL is not correct as far as the ONVIF standard is concerned, this is just for testing)

and each time I would get

<!DOCTYPE html><html lang='en'><head><title>415 Unsupported Media Type</title></head><body><h1>415 Unsupported Media Type</h1></body></html>

I also altered the command, trying without the charset or just using application/xml, but again to no avail.

As for my configuration (be aware that I am using two different fcgi servers on different ports, but this is also somewhat in development phase):

server.modules = (

server.document-root        = "/mnt/mtd/ipc/web" 
server.upload-dirs          = ( "/mnt/mtd/ipc/uploads" )
server.errorlog             = "/tmp/error.log"             = "/mnt/mtd/ipc/" 
server.username             = "root" 
server.groupname            = "root" 
server.port                 = 80

# strict parsing and normalization of URL for consistency and security
# (might need to explicitly set "url-path-2f-decode" = "disable" 
#  if a specific application is encoding URLs inside url-path)
server.http-parseopts = (
  "header-strict"           => "enable",# default
  "host-strict"             => "enable",# default
  "host-normalize"          => "enable",# default
  "url-normalize-unreserved"=> "enable",# recommended highly
  "url-normalize-required"  => "enable",# recommended
  "url-ctrls-reject"        => "enable",# recommended
  "url-path-2f-decode"      => "enable",# recommended highly (unless breaks app)
 #"url-path-2f-reject"      => "enable",
  "url-path-dotseg-remove"  => "enable",# recommended highly (unless breaks app)
 #"url-path-dotseg-reject"  => "enable",
 #"url-query-20-plus"       => "enable",# consistency in query string

index-file.names            = ( "index.php", "index.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

deflate.cache-dir          = "/tmp/compress/" 
#added "application/soap+xml" during my attempts to solve my problem
deflate.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain","application/soap+xml" ) 

# default listening port for IPv6 falls back to the IPv4 port
## Use ipv6 if available
#include_shell "/usr/share/lighttpd/ " + server.port
#include_shell "/usr/share/lighttpd/" 
#include "/etc/lighttpd/conf-enabled/*.conf" 

#server.compat-module-load   = "disable" 
server.modules += (

fastcgi.server = ( ".cgi" => ((                         
                     "bin-path" => "/bin/fcgi_server",
                     "socket" => "/tmp/instt_fcgi.socket",
                        "max-procs" => 1,      
                        "check-local" => "disable" 

mimetype.assign  += ( ".png"  => "image/png",
                      ".jpg"  => "image/jpeg",
                      ".jpeg" => "image/jpeg",
                      ".html" => "text/html",
                      ".txt"  => "text/plain",
#the following line was added by me as an attempt so solve my problem, I also tried "" rather than ".xml" also weird stuff like ".onvif" 
                      ".xml"  => "application/soap+xml" )
$SERVER["socket"] == ":81" {
    fastcgi.server = (
       "/onvif" =>
          ("onvifapp" =>
            "bin-path" => "/home/fcgitestARM.fcgi",
            "socket" => "/tmp/onvifapp.socket",
 #           "port" => 81,
            "max-procs" => 1,
            "check-local" => "disable" 

and my lighttpd version:

lighttpd/1.4.60 - a light and fast webserver

Event Handlers:

        + select (generic)
        + poll (Unix)
        + epoll (Linux)
        - /dev/poll (Solaris)
        - eventports (Solaris)
        - kqueue (FreeBSD)
        - libev (generic)

Network handler:

        + linux-sendfile
        - freebsd-sendfile
        - darwin-sendfile
        - solaris-sendfilev
        + writev
        + write
        - mmap support


        + IPv6 support
        + zlib support
        - zstd support
        - bzip2 support
        - brotli support
        + crypt support
        - OpenSSL support
        - mbedTLS support
        - NSS crypto support
        - GnuTLS support
        - WolfSSL support
        - Nettle support
        + PCRE support
        - MySQL support
        - PgSQL support
        - DBI support
        - Kerberos support
        - LDAP support
        - PAM support
        - memcached support
        - FAM support
        - LUA support
        - xml support
        - SQLite support
        - GDBM support

Any help would be greatly appreciated. In any case, stay healthy and have a nice day.

Replies (2)

RE: Fixing 415 Unsupported Media Error - Added by gstrauss 3 months ago

lighttpd does not care about the Content-Type sent with the request and will send the request to your backend.
lighttpd base modules do not send 415 Unsupported Media Type, except for mod_webdav, which you are not using, so it is likely that lighttpd is sending the request to your FastCGI program and your FastCGI program is rejecting it. Either that or you are not running the lighttpd configuration you think you are running -- make sure that you properly restart lighttpd after changing the configuration. Another option is that some proxy is intercepting the request before it reaches lighttpd. Among these options, the most likely is that your own FastCGI is the issue, so I would recommend starting there. Add some trace to your FastCGI and check that your FastCGI is being sent the request.

Also, the following does not precisely match anything that lighttpd might send in a response, so the response very likely originates elsewhere (e.g. from your FastCGI backend)
<!DOCTYPE html><html lang='en'><head><title>415 Unsupported Media Type</title></head><body><h1>415 Unsupported Media Type</h1></body></html>

RE: Fixing 415 Unsupported Media Error - Added by Jay 3 months ago

Thank you! That completely solved my problem. It was indeed due to my fastcgi backend.

I apologize for wrongfully accusing lighttpd!

In case anyone else may have the same problem and end up here after searching:

I am using fastcgi++. As it turns out, it handles only application/x-www-form-urlencoded and multipart/form-data by default. Anything else gets rejected with the error message I got. This happens before any of my logging functions get to see anything, so I ended up suspecting lighttpd. My bad.

To solve this in fastcgi++, there is a function inProcessor() that gets called when any non-default data type is seen. By default, it returns false which leads to the error. If it returns true, then fastcgi++ proceeds without problem, so one would need to override it.

namespace fcgi
    class fastcgiclass : public Fastcgipp::Request<char>
        ~fastcgiclass() = default;
        bool inProcessor(); 
        bool response() override;

and then define it however one needs, e.g.

bool ServerImpl::inProcessor()
    if(environment().contentType==std::string("application/soap+xml")) {
        return true; } //you might wanna do some more processing
    return false;