Received error about getting "array" and expecting "map" while my YAML seems right

8/30/2018

I'm using k8s 1.11.2 to build my service, the YAML file looks like this:

Deployment

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx-test
  namespace: default
  labels:
  - type: test 
spec:
  replicas: 1
  selector:
    matchLabels:
    - type: test 
  template:
    metadata:
      labels:
      - type: test 
    spec:
      containers:
      - image: nginx:1.14
        name: filebeat
        ports:
        - containerPort: 80

Service

apiVersion: v1
kind: Service
metadata:
    labels:
    - type:test
spec:
  type: ExternalName
  externalName: my.nginx.com
  externalIPs:
  - 192.168.125.123
  clusterIP: 10.240.20.1
  ports: 
  - port: 80
    name: tcp
  selector:
  - type: test

and I get this error:

error validating data: [ValidationError(Service.metadata.labels): invalid type for io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta.labels: got "array", expected "map", ValidationError(Service.spec.selector): invalid type for io.k8s.api.core.v1.ServiceSpec.selector: got "array", expected "map"];

I am sure the format of my YAML file is right, because I used the website http://www.yamllint.com/ to validate it.

Why am I getting this error?

-- 李向朋
kubernetes
yaml

3 Answers

8/30/2018

yamllint.com is a dubious service because it does not tell us which YAML version it is checking against and which implementation it is using. Avoid it.

More importantly, while your input may be valid YAML, this does not mean that it is a valid input for kubernetes. YAML allows you to create any kind of structure, while kubernetes expects a certain structure from you. This is what the error is telling you:

got "array", expected "map"

This means that at a place where kubernetes expects a mapping you provided an array (sequence in proper YAML terms). The error message also gives you the path where this problem occurs:

ValidationError(Service.metadata.labels):

A quick check on metadata labels in kubernetes reveals this documentation, which states that labels need to be mappings, not arrays.

So in your input, the last line here is the culprit:

metadata:
  name: nginx-test
  namespace: default
  labels:
  - type: test

- is a YAML indicator for a sequence item, creating a sequence as value for the key labels:. Dropping it will make it a mapping instead:

metadata:
  name: nginx-test
  namespace: default
  labels:
    type: test
-- flyx
Source: StackOverflow

8/30/2018

In yaml formatting the character "-" implies the start of an array.

You have:

apiVersion: v1
kind: Service
metadata:
    labels:
    - type:test

You want:

apiVersion: v1
kind: Service
metadata:
    labels:
      type:test
-- Connolly
Source: StackOverflow

8/30/2018

The problem is in your second file:

apiVersion: v1
kind: Service
metadata:
    labels:
    - type:test
        #  ^

Above the caret (^) it is missing a space making type:test a single scalar (string) instead of the mapping which is what you get through using

apiVersion: v1
kind: Service
metadata:
    labels:
    - type: test

and what is that you program expects.

Both are valid YAML so primitive syntax checking doesn't help you.

-- Anthon
Source: StackOverflow