All Products
Search
Document Center

Simple Message Queue (formerly MNS):Request protocol

Last Updated:Mar 11, 2026

Simple Message Queue (formerly MNS), or SMQ, uses HTTP-based API requests. This topic covers request syntax, common headers, response format, and request signing.

Important

SMQ SDKs handle request signing automatically. Use an SDK unless you need to construct raw HTTP requests manually.

Request syntax

Regions and endpoints

SMQ is available in multiple regions. Each region provides a public endpoint and an internal endpoint. For details, see Regions and endpoints.

Request methods

SMQ supports PUT, POST, GET, and DELETE over HTTP. Ensure that the request parameters, request headers, and request body are valid. All requests and responses use UTF-8 encoding.

Common parameters

Common request headers

HeaderRequiredDescription
AuthorizationYesAuthentication string. See Sign requests.
Content-LengthYesSize of the request body in bytes.
Content-TypeYesMIME type of the request body. Valid values: text and xml.
Content-MD5NoMD5 hash of the request body. See RFC 1864.
DateYesRequest timestamp in GMT. SMQ rejects requests older than 15 minutes.
HostRequired for HTTP/1.1, optional for HTTP/1.0The SMQ server. Format: $AccountId.mns.cn-hangzhou.aliyuncs.com. Replace $AccountId with your Alibaba Cloud account ID, available in the Alibaba Cloud console.
x-mns-versionYesAPI version. Current version: 2015-06-06.
x-mns-dateNoReplaces the Date header when the client does not support Date.

Common response headers

HeaderDescription
Content-LengthSize of the response body in bytes.
ConnectionHTTP connection status.
DateResponse timestamp in GMT.
ServerSMQ server name.
x-mns-request-idUnique request ID. Include this value when you open a support ticket.
x-mns-versionAPI version. Current version: 2015-06-06.

Response format

HTTP 2xx status codes indicate success. HTTP 4xx and 5xx status codes indicate failure. Success responses use XML:

<?xml version="1.0" encoding="utf-8"?>
<RootElement xmlns="http://mns.aliyuncs.com/doc/v1/">
  <!-- Response data -->
</RootElement>

Error responses also use XML and include the error code, error message, request ID, and host ID. The request ID is globally unique.

<?xml version="1.0" encoding="utf-8"?>
<Error xmlns="http://mns.aliyuncs.com/doc/v1/">
  <Code>ErrorCode</Code>
  <Message>Descriptive error message.</Message>
  <RequestId>Request ID</RequestId>
  <HostId>Host ID</HostId>
</Error>

For a full list of error codes, see Error codes.

Request signature method

SMQ authenticates every API request through a signature in the Authorization header. The signing process has three steps:

  1. Construct a string-to-sign -- Assemble the HTTP method, headers, and resource path into a canonical string.

  2. Calculate the signature -- Hash the string-to-sign with your AccessKey secret using HMAC-SHA1, then Base64-encode the result.

  3. Add the signature to the request -- Set the Authorization header to MNS <AccessKey ID>:<Signature>.

Step 1: Construct the string-to-sign

Build the StringToSign by concatenating the following values, separated by newline characters (\n):

StringToSign = HttpMethod + "\n"
             + CONTENT-MD5 + "\n"
             + CONTENT-TYPE + "\n"
             + DATE + "\n"
             + CanonicalizedMNSHeaders
             + CanonicalizedResource
ComponentDescription
HttpMethodThe HTTP method in uppercase: PUT, GET, POST, or DELETE.
CONTENT-MD5The MD5 hash of the request body. Leave blank if the Content-MD5 header is not set.
CONTENT-TYPEThe MIME type of the request body. Leave blank if the Content-Type header is not set.
DATEThe request timestamp in GMT. Example: Thu, 07 Mar 2012 18:49:58 GMT. If you use the x-mns-date header instead of Date, use that value here. SMQ returns error code 400 if the timestamp is more than 15 minutes old. See Error codes.
CanonicalizedMNSHeadersAll HTTP headers prefixed with x-mns-, processed as follows: convert header names to lowercase, sort alphabetically, then concatenate each header as <name>:<value>\n.
CanonicalizedResourceThe URI of the requested resource, with the domain and port removed. For example, http://123.123.XX.XX:8080/api/test?code=200 yields /api/test?code=200, and http://www.aliyun.com/mns/help yields /mns/help.

CanonicalizedMNSHeaders construction example (Java):

// Get all request headers
Map<String, String> httpHeaders = request.getHeaders();
// Sort headers and convert names to lowercase
sortHeadersKeyAndToLowerCase(httpHeaders);
// Concatenate x-mns-* headers
Set<String> keySet = httpHeaders.keySet();
for (String key : keySet) {
    if (key.startsWith("x-mns-")) {
        CanonicalizedMNSHeaders.append(key).append(":")
            .append(httpHeaders.get(key)).append("\n");
    }
}
Important

If gateways or other transit proxies exist in your system, use the URI of the original HTTP request for CanonicalizedResource, not the URI as seen by intermediate gateways.

Step 2: Calculate the signature

Apply HMAC-SHA1 (RFC 2104) to the UTF-8-encoded StringToSign, using your AccessKey secret as the key. Then Base64-encode the result:

Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
ComponentDescription
Base64Base64 encoding.
HMAC-SHA1The HMAC-SHA1 algorithm defined in RFC 2104.
AccessSecretThe AccessKey secret that corresponds to the AccessKey ID in the Authorization header.
StringToSignThe string constructed in Step 1.

Step 3: Add the signature to the request

Set the Authorization header:

Authorization: MNS <AccessKey ID>:<Signature>

Example:

Authorization: MNS 15B4D3461F177624****:xQE0diMbL****f3YB+FIEXAMPLE=

Signing examples by language

The following examples show how to generate the Authorization header value for an SMQ request.

Python

import base64
import hashlib
import hmac
import os
from datetime import datetime, timezone


def sign_request(access_key_id, access_key_secret, method, resource,
                 content_type="", content_md5="", mns_headers=None):
    """Generate the Authorization header for an SMQ request."""
    date = datetime.now(timezone.utc).strftime("%a, %d %b %Y %H:%M:%S GMT")

    # Build CanonicalizedMNSHeaders
    canonicalized_headers = ""
    if mns_headers:
        for key in sorted(mns_headers.keys()):
            canonicalized_headers += f"{key.lower()}:{mns_headers[key]}\n"

    string_to_sign = (
        f"{method}\n{content_md5}\n{content_type}\n{date}\n"
        f"{canonicalized_headers}{resource}"
    )

    signature = base64.b64encode(
        hmac.new(
            access_key_secret.encode("utf-8"),
            string_to_sign.encode("utf-8"),
            hashlib.sha1,
        ).digest()
    ).decode("utf-8")

    return {
        "Authorization": f"MNS {access_key_id}:{signature}",
        "Date": date,
        "x-mns-version": "2015-06-06",
    }


# Usage
headers = sign_request(
    access_key_id=os.environ["ALIBABA_CLOUD_ACCESS_KEY_ID"],
    access_key_secret=os.environ["ALIBABA_CLOUD_ACCESS_KEY_SECRET"],
    method="PUT",
    resource="/queues/examplequeue?metaOverride=true",
    content_type="text/xml",
    mns_headers={"x-mns-version": "2015-06-06"},
)

Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class MnsSignature {

    public static Map<String, String> signRequest(
            String accessKeyId, String accessKeySecret,
            String method, String resource,
            String contentType, String contentMd5,
            Map<String, String> mnsHeaders) throws Exception {

        String date = DateTimeFormatter.RFC_1123_DATE_TIME
                .format(ZonedDateTime.now(ZoneOffset.UTC));

        // Build CanonicalizedMNSHeaders
        StringBuilder canonicalizedHeaders = new StringBuilder();
        if (mnsHeaders != null) {
            TreeMap<String, String> sorted = new TreeMap<>();
            mnsHeaders.forEach((k, v) -> sorted.put(k.toLowerCase(), v));
            sorted.forEach((k, v) -> canonicalizedHeaders.append(k)
                    .append(":").append(v).append("\n"));
        }

        String stringToSign = method + "\n" + contentMd5 + "\n"
                + contentType + "\n" + date + "\n"
                + canonicalizedHeaders + resource;

        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(new SecretKeySpec(
                accessKeySecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
        String signature = Base64.getEncoder().encodeToString(
                mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)));

        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "MNS " + accessKeyId + ":" + signature);
        headers.put("Date", date);
        headers.put("x-mns-version", "2015-06-06");
        return headers;
    }
}

Go

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"os"
	"sort"
	"strings"
	"time"
)

func signRequest(accessKeyID, accessKeySecret, method, resource,
	contentType, contentMD5 string, mnsHeaders map[string]string) map[string]string {

	date := time.Now().UTC().Format(time.RFC1123)

	// Build CanonicalizedMNSHeaders
	var keys []string
	for k := range mnsHeaders {
		keys = append(keys, strings.ToLower(k))
	}
	sort.Strings(keys)

	var canonicalized strings.Builder
	for _, k := range keys {
		canonicalized.WriteString(fmt.Sprintf("%s:%s\n", k, mnsHeaders[k]))
	}

	stringToSign := fmt.Sprintf("%s\n%s\n%s\n%s\n%s%s",
		method, contentMD5, contentType, date,
		canonicalized.String(), resource)

	mac := hmac.New(sha1.New, []byte(accessKeySecret))
	mac.Write([]byte(stringToSign))
	signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))

	return map[string]string{
		"Authorization": fmt.Sprintf("MNS %s:%s", accessKeyID, signature),
		"Date":          date,
		"x-mns-version": "2015-06-06",
	}
}

func main() {
	headers := signRequest(
		os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
		os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
		"PUT",
		"/queues/examplequeue?metaOverride=true",
		"text/xml", "",
		map[string]string{"x-mns-version": "2015-06-06"},
	)
	for k, v := range headers {
		fmt.Printf("%s: %s\n", k, v)
	}
}

Signature example

The following example shows a complete signed request and common error responses.

Sample request

PUT /queues/$queueName?metaOverride=true HTTP/1.1
Host: $AccountId.mns.cn-hangzhou.aliyuncs.com
Date: Wed, 08 Mar 2012 12:00:00 GMT
Authorization: MNS 15B4D3461F177624****:xQE0diMbL****f3YB+FIEXAMPLE=

<?xml version="1.0" encoding="UTF-8"?>
<Queue xmlns="http://mns.aliyuncs.com/doc/v1/">
  <VisibilityTimeout>60</VisibilityTimeout>
  <MaximumMessageSize>1024</MaximumMessageSize>
  <MessageRetentionPeriod>120</MessageRetentionPeriod>
  <DelaySeconds>30</DelaySeconds>
</Queue>

Error responses

The following table summarizes common authentication-related errors.

ScenarioHTTP statusError code
AccessKey ID does not exist or is disabled403AccessIDAuthError
Date header is missing or invalid403InvalidArgument
Request arrived more than 15 minutes after the timestamp408TimeExpired

Example 1

403 AccessIDAuthError -- The AccessKey ID does not exist or is disabled:

Content-Type: text/xml
Content-Length: 314
Date: Wed, 18 Mar 2012 08:04:06 GMT
x-mns-request-id: 512B2A634403E52B1956****

<?xml version="1.0" encoding="utf-8"?>
<Error xmlns="http://mns.aliyuncs.com/doc/v1/">
  <Code>AccessIDAuthError</Code>
  <Message>
    AccessID authentication fail, please check your AccessID and retry.
  </Message>
  <RequestId>512B2A634403E52B1956****</RequestId>
  <HostId>mns.cn-hangzhou.aliyuncs.com</HostId>
</Error>

Example 2

403 InvalidArgument -- The Date header is missing or invalid:

Content-Type: text/xml
Content-Length: 274
Date: Wed, 18 Mar 2012 08:04:06 GMT
x-mns-request-id: 512B2A634403E52B1956****

<?xml version="1.0" encoding="UTF-8"?>
<Error xmlns="http://mns.aliyuncs.com/doc/v1/">
  <Code>InvalidArgument</Code>
  <Message>Date Header is invalid or missing.</Message>
  <RequestId>7E1A5CF258F535884403****</RequestId>
  <HostId>mns.cn-hangzhou.aliyuncs.com</HostId>
</Error>

Example 3

408 TimeExpired -- The request arrived more than 15 minutes after the timestamp:

Content-Type: text/xml
Content-Length: 283
Date: Wed, 11 May 2011 09:01:51 GMT
x-mns-request-id: 512B2A634403E52B1956****

<?xml version="1.0" encoding="UTF-8"?>
<Error xmlns="http://mns.aliyuncs.com/doc/v1/">
  <Code>TimeExpired</Code>
  <Message>
    The http request you sent is expired.
  </Message>
  <RequestId>512B2A634403E52B1956****</RequestId>
  <HostId>mns.cn-hangzhou.aliyuncs.com</HostId>
</Error>