function checkRequestHeaders (context, headers, transactionPathPrefix, schemaPathPrefix, schemaPath,
  components, options, schemaCache, jsonSchemaDialect, callback) {
  let schemaHeaders = _.filter(schemaPath.parameters, (param) => { return param.in === 'header'; }),
    // filter out headers for following cases
    reqHeaders = _.filter(headers, (header) => {
      // 1. If header is disabled
      // 2. which need explicit handling according to schema (other than parameters object)
      // 3. which are added by security schemes
      if (options.disabledParametersValidation && header.disabled) {
        return !header.disabled;
      }

      return !_.includes(IMPLICIT_HEADERS, _.toLower(_.get(header, 'key')));
    }),
    mismatchProperty = 'HEADER',
    { includeDeprecated, enableOptionalParameters } = context.computedOptions;

  if (options.validationPropertiesToIgnore.includes(mismatchProperty)) {
    return callback(null, []);
  }
  // 1. for each header, find relevant schemaPath property

  return async.map(reqHeaders, (pHeader, cb) => {
    let mismatches = [],
      resolvedParamValue,
      index = _.findIndex(headers, pHeader); // find actual index from collection request headers

    const schemaHeader = _.find(schemaHeaders, (header) => { return header.name === pHeader.key; });

    if (!schemaHeader) {
      // no schema header found
      if (options.showMissingInSchemaErrors) {
        mismatches.push({
          property: mismatchProperty,
          transactionJsonPath: transactionPathPrefix + `[${index}]`,
          schemaJsonPath: null,
          reasonCode: 'MISSING_IN_SCHEMA',
          reason: `The header ${pHeader.key} was not found in the schema`
        });
      }
      return cb(null, mismatches);
    }

    // assign parameter example(s) as schema examples;
    assignParameterExamples(schemaHeader);

    resolvedParamValue = deserialiseParamValue(schemaHeader, pHeader.value, PARAMETER_SOURCE.REQUEST,
      components, options, schemaCache);

    // header found in spec. check header's schema
    setTimeout(() => {
      if (!schemaHeader.schema) {
        // no errors to show if there's no schema present in the spec
        return cb(null, []);
      }
      checkValueAgainstSchema(context,
        mismatchProperty,
        transactionPathPrefix + `[${index}].value`,
        pHeader.key,
        resolvedParamValue,
        schemaHeader.pathPrefix + '[?(@.name==\'' + schemaHeader.name + '\')]',
        schemaHeader.schema,
        PARAMETER_SOURCE.REQUEST,
        components, options, schemaCache, jsonSchemaDialect, cb
      );
    }, 0);
  }, (err, res) => {
    let mismatches = [],
      mismatchObj,
      reqBody = _.get(schemaPath, 'requestBody'),
      contentHeaderMismatches = [],
      filteredHeaders;

    // resolve $ref in request body if present
    if (reqBody) {
      if (_.has(reqBody, '$ref')) {
        reqBody = resolveRefFromSchema(context, reqBody.$ref);
      }

      contentHeaderMismatches = checkContentTypeHeader(headers, transactionPathPrefix,
        schemaPathPrefix + '.requestBody.content', _.get(reqBody, 'content'),
        mismatchProperty, options);
    }

    filteredHeaders = _.filter(schemaHeaders, (h) => {
      // exclude non-required, non-composite and implicit header from further validation
      const isImplicitHeader = _.includes(IMPLICIT_HEADERS, _.toLower(h.name));

      if (VALIDATE_OPTIONAL_PARAMS) {
        return !h.isComposite && !isImplicitHeader;
      }
      return h.required && !h.isComposite && !isImplicitHeader;
    });

    _.each(filteredHeaders, (header) => {
      if (!_.find(reqHeaders, (param) => { return param.key === header.name; })) {

        if (header.deprecated && !includeDeprecated) {
          return;
        }

        // If optional parameters are disabled, do not report them as missing
        if (!enableOptionalParameters && header.required !== true) {
          return;
        }

        // assign parameter example(s) as schema examples;
        assignParameterExamples(header);

        mismatchObj = {
          property: mismatchProperty,
          transactionJsonPath: transactionPathPrefix,
          schemaJsonPath: header.pathPrefix + '[?(@.name==\'' + header.name + '\')]',
          reasonCode: 'MISSING_IN_REQUEST',
          reason: `The required header "${header.name}" was not found in the transaction`
        };

        if (options.suggestAvailableFixes) {
          const resolvedSchema = resolveSchema(context, header.schema, {
            resolveFor: PROCESSING_TYPE.VALIDATION
          });

          mismatchObj.suggestedFix = {
            key: header.name,
            actualValue: null,
            suggestedValue: {
              key: header.name,
              value: safeSchemaFaker(context, resolvedSchema || {}, PROCESSING_TYPE.VALIDATION,
                PARAMETER_SOURCE.REQUEST, components, SCHEMA_FORMATS.DEFAULT, schemaCache),
              description: getParameterDescription(header)
            }
          };
        }
        mismatches.push(mismatchObj);
      }
    });
    return callback(null, _.concat(contentHeaderMismatches, _.flatten(res), mismatches));
  });
}
Filter out composite params. i.e. Params that contains anyOf/oneOf keyword in schema.
For such params multiple keys are possible based on schema so they should not be reported as missing.