MusicBrainz Search API - HTTP 400 Bad Request

Hi, I’m Sagnik Ganguly! I’m creating an Android application which is a music player and I’m trying to fetch the images of the artists from MusicBrainz but to get the the images I’ve to find the MBID of the artist first and obviously I can’t manually enter the MBID of all the individual artists so I’m trying to retrieve the MBID from https://musicbrainz.org/ws/2/artist?query=Ellie%20Goulding and it’s perfectly working on the browser but in my application I’m getting a HTTP 400 Bad Request error. May I know what is the cause of it?

Here is my Logcat output:

E/XMLPARSER:URL: https://musicbrainz.org/ws/2/artist?query=Arijit%20Singh
E/XMLPARSER:REQUEST: {Accept=[text/html,application/xhtml+xml,application/json,application/xml;q=0.9,image/webp,*/*;q=0.8], Accept-Charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.7], Accept-Encoding=[gzip, deflate, br], Accept-Language=[en-us,en;q=0.5], Connection=[keep-alive], Content-type=[application/xml], Host=[musicbrainz.org], Keep-Alive=[115], User-Agent=[Flow/1.0.1 (sagnikganguly2012@rediffmail.com)]}

E/XMLPARSER:RESPONSE: {null=[HTTP/1.1 400 Bad Request], Access-Control-Allow-Origin=[*], Connection=[keep-alive], Content-Length=[167], Content-Type=[application/json; charset=utf-8], Date=[Sat, 30 Jan 2021 13:36:27 GMT], ETag=["12537101369f5abd47cc74cb0dd23771"], Keep-Alive=[timeout=15], Server=[Plack::Handler::Starlet], X-Android-Received-Millis=[1612013787903], X-Android-Response-Source=[NETWORK 400], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1612013787070], X-RateLimit-Limit=[1200], X-RateLimit-Remaining=[771], X-RateLimit-Reset=[1612013787]}
D/XMLPARSER:: http response code is 400 : Bad Request

Here is my code:

private String request(String urlString) {
	final StringBuilder sb = new StringBuilder();
	try{
		URL url = new URL(urlString);
		URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
		urlString = uri.toASCIIString();
		url = new URL(urlString);
		HttpURLConnection connection = (HttpURLConnection)url.openConnection();
		connection.setRequestMethod("GET");
		connection.setRequestProperty("Host", "musicbrainz.org");
		connection.setRequestProperty("User-Agent", "Flow/1.0.1 (sagnikganguly2012@rediffmail.com)");
		connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/json,application/xml;q=0.9,image/webp,*/*;q=0.8");
		connection.setRequestProperty("Accept-Language", "en-us,en;q=0.5");
		connection.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
		connection.setRequestProperty("Keep-Alive", "115");
		connection.setRequestProperty("Connection", "keep-alive");
		connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
		connection.setRequestProperty("Content-type", "application/xml");
		connection.setDoInput(true);
		connection.setDoOutput(true);
		Log.e("XMLPARSER:URL", urlString);//request headers)
		Log.e("XMLPARSER:REQUEST", connection.getRequestProperties().toString());//request headers)
		//Log.e("XMLPARSER:REQUEST", connection.get().toString());//request headers)
		connection.connect();

		Log.e("XMLPARSER:RESPONSE", connection.getHeaderFields().toString()); //response headers
		//Log.e("XMLPARSER:", conn.getResponseCode());//response http code
		InputStream inputStream;
		if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
			Log.d("XMLPARSER:", "http response code is " + connection.getResponseCode()+" : "+connection.getResponseMessage());
			//return null;
			inputStream = new GZIPInputStream(connection.getErrorStream());
		} else
			inputStream = new GZIPInputStream(connection.getInputStream());

		//InputStream inputStream = connection.getInputStream();

		BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream));
		String line = "";
		while ((line = rd.readLine()) != null) {
			sb.append(line).append("\n");
		}
		Log.d("XMLPARSER:", "RESPONSE: " + sb.toString());
	}
	catch (IOException | URISyntaxException e) {
		// Writing exception to log
		e.printStackTrace();
	}
	return sb.toString();
}
2 Likes

I checked logs: method used was POST, which explains the 400 answer. Your code seems to set method to GET, but perhaps it isn’t working as expected.

3 Likes

How can you be so sure that the request is sent via “POST”? As you can see I’m setting the request method to “GET”:

connection.setRequestMethod(“GET”);

1 Like

Because I, as MetaBrainz sysadmin, have access to web logs for this service, and did some research using the user agent you are using.
Whatever your code is (and yes, I saw connection.setRequestMethod(“GET”);), be certain requests were done using POST, this is why you get 400 responses.

4 Likes

Okay thanks for helping me out. You were right. I’ve just found something on StackOverflow:

The httpCon.setDoOutput(true); implicitly set the request method to POST because that’s the default method whenever you want to send a request body.

I’m fixing the code right now if I face any problems I’ll post here I hope you’ll help me again.

3 Likes

Hurray for APIs with unexpected side effects :slight_smile:

2 Likes

Hello sir, after figuring out what the problem was I’m still getting HTTP 400 error.
Here is my updated method:

private String request(String urlString) {
		final StringBuilder sb = new StringBuilder();
		try{
			URL url = new URL(urlString);
			URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
			urlString = uri.toASCIIString();
			url = new URL(urlString);
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Host", "musicbrainz.org");
			connection.setRequestProperty("User-Agent", "Flow/1.0.1 (sagnikganguly2012@rediffmail.com)");
			connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/json,application/xml;q=0.9,image/webp,*/*;q=0.8");
			connection.setRequestProperty("Accept-Language", "en-us,en;q=0.5");
			connection.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
			connection.setRequestProperty("Keep-Alive", "115");
			connection.setRequestProperty("Connection", "keep-alive");
			connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
			connection.setRequestProperty("Content-type", "application/xml");
			connection.setDoInput(true);
			//connection.setDoOutput(true);
			Log.e("XMLPARSER:REQUEST[URL]:", urlString);
			Log.e("XMLPARSER:REQUEST[HEADER]:", connection.getRequestProperties().toString());
			connection.connect();

			Log.e("XMLPARSER:RESPONSE[HEADER]:", connection.getHeaderFields().toString());
			Log.d("XMLPARSER:RESPONSE[CODE]:", "http response code is " + connection.getResponseCode()+" : "+connection.getResponseMessage());

			InputStream inputStream = connection.getInputStream();
			BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream));
			String line;

			while ((line = rd.readLine()) != null) {
				sb.append(line).append("\n");
			}

			Log.d("XMLPARSER:RESPONSE[BODY]:", "RESPONSE: " + sb.toString());
		}
		catch (IOException | URISyntaxException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

Here is my Log:

E/XMLPARSER:REQUEST[URL]:: https://musicbrainz.org/ws/2/artist?query=Arijit%20Singh

E/XMLPARSER:REQUEST[HEADER]:: {Accept=[text/html,application/xhtml+xml,application/json,application/xml;q=0.9,image/webp,*/*;q=0.8], Accept-Charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.7], Accept-Encoding=[gzip, deflate, br], Accept-Language=[en-us,en;q=0.5], Connection=[keep-alive], Content-type=[application/xml], Host=[musicbrainz.org], Keep-Alive=[115], User-Agent=[Flow/1.0.1 (sagnikganguly2012@rediffmail.com)]}

E/XMLPARSER:RESPONSE[HEADER]:: {null=[HTTP/1.1 400 Bad Request], Cache-Control=[no-cache, no-store], Connection=[keep-alive], Content-Length=[137], Content-Type=[application/json], Date=[Mon, 01 Feb 2021 16:16:38 GMT], ETag=["1775e61b777"], Expires=[Sat, 01 Jan 2000 01:00:00 GMT], Keep-Alive=[timeout=15], Last-Modified=[Mon, 01 Feb 2021 16:16:38 GMT], Pragma=[no-cache], X-Android-Received-Millis=[1612196214082], X-Android-Response-Source=[NETWORK 400], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1612196199008], X-RateLimit-Limit=[1200], X-RateLimit-Remaining=[867], X-RateLimit-Reset=[1612196199]}

E/XMLPARSER:RESPONSE[CODE]:: HTTP Response code is 400 : Bad Request

Additionally, the HTTPUrlConnection is throwing a FileNotFoundException:

W/System.err: java.io.FileNotFoundException: https://musicbrainz.org/ws/2/artist?query=Arijit%20Singh
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:251)
W/System.err:     at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
W/System.err:     at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:26)
        at ga.sgsoft.android.flowmusic.helpers.XMLParser.request(XMLParser.java:70)
W/System.err:     at ga.sgsoft.android.flowmusic.helpers.XMLParser.getXMLFromUrl(XMLParser.java:87)
        at ga.sgsoft.android.flowmusic.model.ArtistModel.getMbid(ArtistModel.java:78)
        at ga.sgsoft.android.flowmusic.model.ArtistModel.getMBID(ArtistModel.java:29)
W/System.err:     at ga.sgsoft.android.flowmusic.ui.fragments.pages.library.HomeLibraryFragment.lambda$onViewCreated$0$HomeLibraryFragment(HomeLibraryFragment.java:68)
        at ga.sgsoft.android.flowmusic.ui.fragments.pages.library.-$$Lambda$HomeLibraryFragment$RFOVdm17DmjdCcpOfFVEjTJSg2s.run(Unknown Source:2)
W/System.err:     at java.lang.Thread.run(Thread.java:764)

Hard to tell, but it seems you expect xml and use following headers:

Accept: text/html,application/xhtml+xml,application/json,application/xml;q=0.9,image/webp,*/*;q=0.8

It will return response in json format (because application/json is before application/xml).

For the 400 error, not sure, try to remove:

			connection.setRequestProperty("Accept-Language", "en-us,en;q=0.5");
			connection.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
			connection.setRequestProperty("Keep-Alive", "115");
			connection.setRequestProperty("Connection", "keep-alive");
			connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
			connection.setRequestProperty("Content-type", "application/xml");

those aren’t strictly needed.
Also doesn’t your API set Host from passed url?

4 Likes

Thank you so much sir. It’s working perfectly now. Here is the output:

2021-02-03 19:07:17.896 2723-3118/ga.sgsoft.android.flowmusic E/XMLPARSER:REQUEST[URL]:: https://musicbrainz.org/ws/2/artist?query=Arijit%20Singh
2021-02-03 19:07:17.898 2723-3118/ga.sgsoft.android.flowmusic E/XMLPARSER:REQUEST[HEADER]:: {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8], User-Agent=[Flow/1.0.1 (sagnikganguly2012@rediffmail.com)]}
2021-02-03 19:07:20.371 2723-3118/ga.sgsoft.android.flowmusic E/XMLPARSER:RESPONSE[HEADER]:: {null=[HTTP/1.1 200 OK], Access-Control-Allow-Origin=[*], Connection=[keep-alive], Content-Type=[application/xml; charset=UTF-8], Date=[Wed, 03 Feb 2021 13:37:16 GMT], ETag=["OGUxODc0MDAwMDAwMDAwMFNvbHI="], Keep-Alive=[timeout=15], Last-Modified=[Wed, 03 Feb 2021 13:33:17 GMT], Transfer-Encoding=[chunked], Vary=[Accept-Encoding], X-Android-Received-Millis=[1612359440368], X-Android-Response-Source=[NETWORK 200], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1612359439762], X-Cache-Status=[STALE], X-RateLimit-Limit=[1200], X-RateLimit-Remaining=[1101], X-RateLimit-Reset=[1612359438]}
2021-02-03 19:07:20.389 2723-3118/ga.sgsoft.android.flowmusic E/XMLPARSER:: READING XML: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><metadata created="2021-02-03T13:36:00.806Z" xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ns2="http://musicbrainz.org/ns/ext#-2.0"><artist-list count="465" offset="0"><artist id="ed3f4831-e3e0-4dc0-9381-f5649e9df221" type="Person" type-id="b6e035f4-3ce9-331c-97df-83397230b0df" ns2:score="100"><name>Arijit Singh</name><sort-name>Singh, Arijit</sort-name><gender id="36d3d30a-839d-3eda-8cb3-29be4384e4a9">male</gender><country>IN</country><area id="d31a9a15-537f-3669-ad53-25753ddd2772" type="Country" type-id="06dd0ae4-8c74-30bb-b43d-95dcedf961de"><name>India</name><sort-name>India</sort-name><life-span><ended>false</ended></life-span></area><begin-area id="d31a9a15-537f-3669-ad53-25753ddd2772" type="Country" type-id="06dd0ae4-8c74-30bb-b43d-95dcedf961de"><name>India</name><sort-name>India</sort-name><life-span><ended>false</ended></life-span></begin-area><life-span><begin>1987-04-25</begin><ended>false</ended></life-span><alias-list><alias sort-name="Singh, Arjit">Arjit Singh</alias></alias-list><tag-list><tag count="1"><name>bollywood</name></tag></tag-list></artist><artist id="268141c4-9a27-44d8-b5c2-d1d4a00342bb" ns2:score="34"><name>Arijit Datta</name><sort-name>Arijit Datta</sort-name><life-span><ended>false</ended></life-span></artist><artist id="847188c4-8876-4df3-a5f3-b4ef2b6d741b" ns2:score="34"><name>Dev Arijit</name><sort-name>Arijit, Dev</sort-name><disambiguation>sang a song in Mukkabaaz</disambiguation><life-span><ended>false</ended></life-span></artist><artist id="ff7d390f-03be-40e4-9210-3e0f660966df" type="Person" type-id="b6e035f4-3ce9-331c-97df-83397230b0df" ns2:score="30"><name>Jagjit Singh</name><sort-name>Singh, Jagjit</sort-name><gender id="36d3d30a-839d-3eda-8cb3-29be4384e4a9">male</gender><country>IN</country><area id="d31a9a15-537f-3669-ad53-25753ddd2772" type="Country" type-id="06dd0ae4-8c74-30bb-b43d-95dcedf961de"><name>India</name><sort-name>India</sort-name><life-span><ended>false</ended></life-span></area><begin-area id="d31a9a15-537f-3669-ad53-25753ddd2772" type="Country" type-id="06dd0ae4-8c74-30bb-b43d-95dcedf961de"><name>India</name><sort-name>India</sort-name><life-span><ended>false</ended></life-span></begin-area><end-area id="e24de96f-81de-4021-8af3-1b656b6b1e42" type="City" type-id="6fd8f29a-3d0a-32fc-980d-ea697b69da78"><name>Mumbai</name><sort-name>Mumbai</sort-name><life-span><ended>false</ended></life-span></end-area><isni-list><isni>0000000109340667</isni></isni-list><life-span><begin>1941-02-08</begin><end>2011-10-10</end><ended>true</ended></life-span><alias-list><alias sort-name="Singh Jagjeet" type="Artist name" type-id="894afba6-2816-3c24-8072-eadb66bd04bc">Jagjeet Singh</alias><alias locale="hi_IN" sort-name="सिंह जगजीत" type="Artist name" type-id="894afba6-2816-3c24-8072-eadb66bd04bc" primary="primary">जगजीत सिंह</alias></alias-list><tag-list><tag count="3"><name>ghazal</name></tag><tag count="1"><name>ग़ज़ल</name></tag></tag-list></artist><artist id="9a3dc805-9d47-4d67-b59d-47e1bfb82537" type="Person" type-id="b6e035f4-3ce9-331c-97df-83397230b0df" ns2:score="28"><name>Chitra Singh</name><sort-name>Singh, Chitra</sort-name><gender id="93452b5a-a947-30c8-934f-6a4056b151c2">female</gender><life-span><ended>false</ended></life-span></artist><artist id="d5812475-f8e6-4b5c-951f-7e82720ef041" type="Person" type-id="b6e035f4-3ce9-331c-97df-83397230b0df" ns2:score="28"><name>Sukhwinder Singh</name><sort-name>Singh, Sukhwinder</sort-name><gender id="36d3d30a-839d-3eda-8cb3-29be4384e4a9">male</gender><country>IN</country><area id="d31a9a15-537f-3669-ad53-25753ddd2772" type="Country" type-id="06dd0ae4-8c74-30bb-b43d-95dcedf961de"><name>India</name><sort-name>India</sort-name><life-span><ended>false</ended></life-span></area><life-span><begin>1968-07-18</begin><ended>false</ended></life-span><alias-list><alias sort-name="Sukhwindher Singh">Sukhwindher Singh</alias><alias sort-name="Sukvinder Singh">Sukvinder Singh</alias><alias sort

By the way, only one more question, how can I get output in JSON format?

Take your URL:

https://musicbrainz.org/ws/2/artist?query=Arijit%20Singh

And append fmt=json:

https://musicbrainz.org/ws/2/artist?query=Arijit%20Singh&fmt=json
4 Likes

Thank you very much. I’ll try it out.

1 Like

To get json you can also set header Accept: application/json on your request (and drop &fmt=json from URL if you do).

5 Likes

By the way, is there any way to retrieve Artist image (beyond MusicBrainz)? If yes, can you explain or show an example for Android (Java)?

8 posts were split to a new topic: No MusicBrainz search results with Mp3Tag script