tavis nörttimaailmassa

EksisONE - artikkeleita ja ohjeita nörttimaailmasta

Error 404: AH00687: Negotiation: discovered file(s) matching request: /var/www/html/site (None could be negotiated).

Google search console lähetti ilmoituksen parista error 404:stä wordpress-sivustolla. Se ihmetytti, koska 404:sten monitorointi ei kertonut mitään.  Tieto puuttuvasta osoitteesta ei siis ollut tullut WordPressille asti. Kokeilin ilmoitettuja linkkejä ja sain ruudulle Apachen 404-ilmoituksen. Vilkaisin artikkeleihin ja kategorioihin varmistuakseni, että ne ylipäätään olivat olemassa, eikä siltä akselilta löytynyt mitään ihmeellistä. Silti yksi määrätty kategoria ja kaikki siihen kuuluvat postaukset herjasivat error 404 Not Found. Uhrasin tunnin elämästäni tarkastaessani kaikki redirectit ja lopulta poistinkin jokaisen: ei auttanut. Kuppi kahvia, tauko ja google auki. Syyllinenkin löytyi.

Virheiden selvittäminen suurin vaikeus on löytää oikeat hakusanat. Minulla oli aikoinaan ongelmia Moodlen kanssa, joka ei päästänyt kirjautumisia läpi. Erilaiset variaatiot Googlen hauissa tarjosivat minulla koko ajan samoja osumia, joista yksikään ei auttanut. Lopulta ongelma selvisi aivan vahingossa erään toisen selvittämisen ohessa ja syylliseksi paljastui Hitch sekä HTTP/2 – korjausta ei kuitenkaan löytynyt. Mutta kun sain yhdistettyä samaan hakuun Moodlen, kirjautumisongelman ja HTTP/2:den, niin löysin muitakin saman asian kanssa painineita – siihen asti luulin olevani ainoa maailmassa.

Omituisen error 404 not found ilmoituksella urlille, joka on olemassa, kanssa on kyse aivan samasta. Pelkän WordPressin 404-ongelmien etsiminen tarjoaa pelkästään (väsyneitä) osumia kehoitukseen päivittää osoiterakenne, joka ei auta ainakaan tässä yhtään mitään. Tarvitsin siis jotain vähän spesifisempää.

Vilkaisin Apache2:den tapahtumalogin.

cat /var/log/apache2/access.log

Se ei kertonut mitään hyödyllistä, vaan toisti jo tietämäni: error 404. Joten vilkaisin error-login.

cat /var/log/apache2/error.log

Nyt sain selvämpää tietoa: Error 404: AH00687: Negotiation: discovered file(s) matching request: /var/www/html/site (None could be negotiated).

Google töihin ja ensimmäinen osuma kuvaili vastaavanlaista ongelmaa kuin minulla. Ei aivan, mutta riittävän lähelle. Ratkaisu oli ollut poistaa Apachen virtual hostin lohkosta <Directory /var/www/html/> riviltä Options asetus +MultiViews. Tein sen, uudelleenkäynnistin Apache2:den ja ongelma hävisi.

Kaikki olisi muuten hyvin, mutta +MultiViews neuvotaan suunnilleen jokaisessa ohjeessa ja Apache laittaa sen itse oletuksena. Plus se on ollut paikallaan vuosia ja ilman ongelmia. En tiedä mitä se tekee ja miksi se meni nyt rikki. Miksi kohtaan saattaa ehkä liittyä se, että samaan aikaan fail2ban laitettiin vahtimaan koputtelijoita ja muita rosmoja. Lisäksi päivitin serverin enkä tiedä yhtään mitä siinä päivitettiin, lähdin silloin tupakalle. Olen tehnyt viime aikoina paljon muitakin säätöjä, joten selvää aiheuttajaa en lähtenyt edes arvailemaan.

Periaatteessa voisin tyytyä siihen, että sain ongelman korjattua, vaikka en tiennyt miksi. Se ei ole järkevää, vaan asiat kannattaa opetella (toki, olin asettanut sen tietämättä mitä tein, mutta aivan kaikkea ei voi kerralla opetella).

Options: +MultiViews

MultiViews mahdollistaa Apachelle sopivan tiedoston hakemisen, kun pyydetään jotain mitä ei löydy. Silloin Apache menee sen hakemiston läpi, jossa MultiViews on sallittu ja yrittää löytää pyyntöön sopivan tiedoston. Jos ei löydy (tai Apachen mielestä löytyy, mutta se ei tiedä mitä tehdä sen kanssa), niin Apache antaa error 404. Useimpien osumien mukaan MultiViews on käytössä, kun tarjotaan useampikielistä sivustoa – ja joka kerta paikalle tuli aina joku, joka sanoi, että sitä ei kuulu käyttää siihen.

Idea on siinä, että annetaan vaikka linkki https://www.example.tld/index.html jota ei ole. Sen sijaan juuresta löytyy vaikka

  • index.fi.html
  • index.se.html
  • index.en.hml

jolloin Apache2 päättää +MultiViews asetuksen sallimana valikoida näytettäväksi index.fi|se|en.html selaimen kieliasetuksen mukaan.

Osa taasen totesi, että koska MultiViews on luonteeltaan redirect, niin se aika ajoin riitelee virtual hostin muiden uudelleenohjausten kanssa, mutta kukaan ei oikein osannut sanoa miten, missä ja miksi.

Tuo antoi minulle kuitenkin selvän johtolangan. Koska osoite www.example.tld/site kaatui MultiViewsiin, niin se tarkoittaa, että Apache oli vakaasti sitä mieltä, että

  • tiedostoa site ei ole olemassa, tai
  • löytyy jotain vastaavaa, mutta Apache ei tiedä mitä sille tekisi

Joten sivuston kotihakemiston juuri auki ja ihmettelemään. Ja ylläripylläri, sieltä löytyi tiedosto site.webmanifest. Apache oli yrittänyt sitä auki joka kerta siten sijaan, ja koska tiedostomuodolle .webmanifest ei ole määritelty mime-tyyppiä, niin lopputulos oli error 404.

Nyt arvailen, mutta juonen kulku taisi olla tällainen:

  • jos osoitteessa päättävä / , niin Varnish poistaa sen ennenkuin kyselee osoitetta Apachelta; silloin osoite näyttäisi viittaavan tiedostoon (joka siis WordPressin kategoria teknisesti onkin, ja kaikki WordPressin osoitteet aidosti väittävät olevansa joku/sivu-tai-kategoria/index.html, josta meille ei vaan näytetä index.html kohtaa ja kaikki hoituu redirectillä)
  • +MultiViews on ennen virtual hostissa olevaa WordPressin uudelleenohjausta, joka rakentaa urlin sekä laittaa kauttaviivan; MultiViews oletti siis, että site on tiedosto
    • Apache ei näämmä piittaa siitäkään, että onko se urlissa kuvaamassa hakemistoa, vaan perkaa urlia sana kerrallaan ja on tyytyväinen ensimmäiseen osumaansa piittaamatta mitä sen jälkeen tulee – itseasiassa Apache toimii aivan kaikessa näin ja siksi järjestys on tärkeä
  • site ei löydy juuresta, joten Apache päätti ottaa lähinnä vastaavan, joka oli site.webmanifest ja epäonnistui

Kun MultiViews oli pois (joko kokonaan poistettuna tai muodossa -MultiViews), niin Apache päästi urlin etenemään ja WordPressin uudelleenohjaukset pelastivat tilanteen.

Minulla on siis aidosti kaksi vaihtoehtoa:

  • pitää MultiViews päällä ja poistaa site.webmanifest
  • pitää site.webmanifest ja poistaa MultiViews

Minä en tarvitse MultiViews-asetusta yhtään mihinkään ja site.webmanifest on JSON-tiedosto, joka kertoo (android)mobiileille mitä ne tekevät, jos sivuston linkki laitetaan pikakuvakkeeksi kotinäytölle. MultiViews siis lähtee ja ongelma on ratkaistu.

Toki voisi ottaa kokonaan pois päältä Apachen negotiation-moduulin, joka MultiViews-asetusta käyttää:

a2dismod negotiation
systemctl restart apache2

mutta olkoot tällä kertaa, koska minulla on kaikissa muissakin virtual hosteissa +MultiViews ja pahaa pelkään, että jos poistan tuon moduulin, niin Apache kaatuu virheelliseksi muuttuneeseen asetukseen. Teen myöhemmin, nyt on kahvipaussin aika.